8 if not ip_forwarding_enabled?
9 warn "NOTE: IP forwarding must be enabled in the kernel."
10 warn "Turning IP forwarding on now."
11 sudo %w(/sbin/sysctl net.ipv4.ip_forward=1)
15 # * Docker is installed and can be found in the user's path
16 # * Docker can be run as a non-root user
17 # - TODO: put the user is in the docker group if necessary
18 # - TODO: mount cgroup automatically
19 # - TODO: start the docker service if not started
21 docker_path = %x(which docker.io).chomp
24 docker_path = %x(which docker).chomp
28 warn "Docker not found."
30 warn "Please make sure that Docker has been installed and"
31 warn "can be found in your PATH."
33 warn "Installation instructions for a variety of platforms can be found at"
34 warn "http://docs.docker.io/en/latest/installation/"
36 elsif not docker_ok? docker_path
37 warn "WARNING: docker could not be run."
38 warn "Please make sure that:"
39 warn " * You have permission to read and write /var/run/docker.sock"
40 warn " * a 'cgroup' volume is mounted on your machine"
41 warn " * the docker daemon is running"
45 # Check that debootstrap is installed.
46 if not debootstrap_ok?
47 warn "Installing debootstrap."
48 sudo '/usr/bin/apt-get', 'install', 'debootstrap'
51 # Generate a config.yml if it does not exist or is empty
52 if not File.size? 'config.yml'
53 print "Generating config.yml.\n"
54 print "Arvados needs to know the email address of the administrative user,\n"
55 print "so that when that user logs in they are automatically made an admin.\n"
56 print "This should be an email address associated with a Google account.\n"
58 admin_email_address = ""
59 until is_valid_email? admin_email_address
60 print "Enter your Google ID email address here: "
61 admin_email_address = gets.strip
62 if not is_valid_email? admin_email_address
63 print "That doesn't look like a valid email address. Please try again.\n"
67 File.open 'config.yml', 'w' do |config_out|
68 config = YAML.load_file 'config.yml.example'
69 config['API_AUTO_ADMIN_USER'] = admin_email_address
70 config['API_HOSTNAME'] = generate_api_hostname
71 config['PUBLIC_KEY_PATH'] = find_or_create_ssh_key(config['API_HOSTNAME'])
72 config.each_key do |var|
73 if var.end_with?('_PW') or var.end_with?('_SECRET')
74 config[var] = rand(2**256).to_s(36)
76 config_out.write "#{var}: #{config[var]}\n"
81 # If all prerequisites are met, go ahead and build.
82 if ip_forwarding_enabled? and
83 docker_ok? docker_path and
85 File.exists? 'config.yml'
86 warn "Building Arvados."
87 system({"DOCKER" => docker_path}, '/usr/bin/make', '-f', options[:makefile], *ARGV)
92 # Execute the arg list 'cmd' under sudo.
93 # cmd can be passed either as a series of arguments or as a
94 # single argument consisting of a list, e.g.:
95 # sudo 'apt-get', 'update'
96 # sudo(['/usr/bin/gpasswd', '-a', ENV['USER'], 'docker'])
97 # sudo %w(/usr/bin/apt-get install lxc-docker)
100 # user can pass a single list in as an argument
101 # to allow usage like: sudo %w(apt-get install foo)
102 warn "You may need to enter your password here."
103 if cmd.length == 1 and cmd[0].class == Array
106 system '/usr/bin/sudo', *cmd
110 # Returns true if its arg looks like a valid email address.
111 # This is a very very loose sanity check.
113 def is_valid_email? str
114 str.match /^\S+@\S+\.\S+$/
117 # generate_api_hostname
118 # Generates a 5-character randomly chosen API hostname.
120 def generate_api_hostname
121 rand(2**256).to_s(36)[0...5]
124 # ip_forwarding_enabled?
125 # Returns 'true' if IP forwarding is enabled in the kernel
127 def ip_forwarding_enabled?
128 %x(/sbin/sysctl -n net.ipv4.ip_forward) == "1\n"
132 # Returns 'true' if debootstrap is installed and working.
135 return system '/usr/sbin/debootstrap --version > /dev/null 2>&1'
139 # Returns 'true' if docker can be run as the current user.
141 def docker_ok?(docker_path)
142 return system "#{docker_path} images > /dev/null 2>&1"
145 # find_or_create_ssh_key arvados_name
146 # Returns the SSH public key appropriate for this Arvados instance,
147 # generating one if necessary.
149 def find_or_create_ssh_key arvados_name
150 ssh_key_file = "#{ENV['HOME']}/.ssh/arvados_#{arvados_name}_id_rsa"
151 unless File.exists? ssh_key_file
154 '-C', "arvados@#{arvados_name}",
158 return "#{ssh_key_file}.pub"
162 # Determines which Docker package is suitable for this Linux distro
163 # and installs it, resolving any dependencies.
164 # NOTE: not in use yet.
167 linux_distro = %x(lsb_release --id).split.last
168 linux_release = %x(lsb_release --release).split.last
169 linux_version = linux_distro + " " + linux_release
170 kernel_release = `uname -r`
174 if not linux_release.match '^1[234]\.'
175 warn "Arvados requires at least Ubuntu 12.04 (Precise Pangolin)."
176 warn "Your system is Ubuntu #{linux_release}."
179 if linux_release.match '^12' and kernel_release.start_with? '3.2'
180 # Ubuntu Precise ships with a 3.2 kernel and must be upgraded.
181 warn "Your kernel #{kernel_release} must be upgraded to run Docker."
183 warn " sudo apt-get update"
184 warn " sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
189 sudo 'apt-get', 'update'
190 sudo 'apt-get', 'install', "linux-image-extra-#{kernel_release}"
193 # add Docker repository
194 sudo %w(/usr/bin/apt-key adv
195 --keyserver keyserver.ubuntu.com
196 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9)
197 source_file = Tempfile.new('arv')
198 source_file.write("deb http://get.docker.io/ubuntu docker main\n")
200 sudo '/bin/mv', source_file.path, '/etc/apt/sources.list.d/docker.list'
201 sudo %w(/usr/bin/apt-get update)
202 sudo %w(/usr/bin/apt-get install lxc-docker)
204 # Set up for non-root access
205 sudo %w(/usr/sbin/groupadd docker)
206 sudo '/usr/bin/gpasswd', '-a', ENV['USER'], 'docker'
207 sudo %w(/usr/sbin/service docker restart)
210 warn "Must be running a Debian or Ubuntu release in order to run Docker."
216 if __FILE__ == $PROGRAM_NAME
217 options = { :makefile => File.join(File.dirname(__FILE__), 'Makefile') }
218 OptionParser.new do |opts|
219 opts.on('-m', '--makefile MAKEFILE-PATH',
220 'Path to the Makefile used to build Arvados Docker images') do |mk|
221 options[:makefile] = mk