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 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 # print "Arvados needs to know the shell login name for the administrative user.\n"
68 # print "This will also be used as the name for your git repository.\n"
71 # until is_valid_user_name? user_name
72 # print "Enter a shell login name here: "
73 # user_name = gets.strip
74 # if not is_valid_user_name? user_name
75 # print "That doesn't look like a valid shell login name. Please try again.\n"
79 File.open 'config.yml', 'w' do |config_out|
80 config_out.write "# If a _PW or _SECRET variable is set to an empty string, a password\n"
81 config_out.write "# will be chosen randomly at build time. This is the\n"
82 config_out.write "# recommended setting.\n\n"
83 config = YAML.load_file 'config.yml.example'
84 #config['API_AUTO_ADMIN_USER'] = admin_email_address
85 #config['ARVADOS_USER_NAME'] = user_name
86 config['API_HOSTNAME'] = generate_api_hostname
87 config['API_WORKBENCH_ADDRESS'] = 'false'
88 config.each_key do |var|
89 config_out.write "#{var}: #{config[var]}\n"
94 # If all prerequisites are met, go ahead and build.
95 if ip_forwarding_enabled? and
96 docker_ok? docker_path and
98 File.exists? 'config.yml'
106 # Execute the arg list 'cmd' under sudo.
107 # cmd can be passed either as a series of arguments or as a
108 # single argument consisting of a list, e.g.:
109 # sudo 'apt-get', 'update'
110 # sudo(['/usr/bin/gpasswd', '-a', ENV['USER'], 'docker'])
111 # sudo %w(/usr/bin/apt-get install lxc-docker)
114 # user can pass a single list in as an argument
115 # to allow usage like: sudo %w(apt-get install foo)
116 warn "You may need to enter your password here."
117 if cmd.length == 1 and cmd[0].class == Array
120 system '/usr/bin/sudo', *cmd
124 # Returns true if its arg looks like a valid email address.
125 # This is a very very loose sanity check.
127 def is_valid_email? str
128 str.match /^\S+@\S+\.\S+$/
131 # is_valid_user_name?
132 # Returns true if its arg looks like a valid unix username.
133 # This is a very very loose sanity check.
135 def is_valid_user_name? str
136 # borrowed from Debian's adduser (version 3.110)
137 str.match /^[_.A-Za-z0-9][-\@_.A-Za-z0-9]*\$?$/
140 # generate_api_hostname
141 # Generates a 5-character randomly chosen API hostname.
143 def generate_api_hostname
144 rand(2**256).to_s(36)[0...5]
147 # ip_forwarding_enabled?
148 # Returns 'true' if IP forwarding is enabled in the kernel
150 def ip_forwarding_enabled?
151 %x(/sbin/sysctl -n net.ipv4.ip_forward) == "1\n"
155 # Returns 'true' if debootstrap is installed and working.
158 return system '/usr/sbin/debootstrap --version > /dev/null 2>&1'
162 # Returns 'true' if docker can be run as the current user.
164 def docker_ok?(docker_path)
165 return system "#{docker_path} images > /dev/null 2>&1"
169 # Determines which Docker package is suitable for this Linux distro
170 # and installs it, resolving any dependencies.
171 # NOTE: not in use yet.
174 linux_distro = %x(lsb_release --id).split.last
175 linux_release = %x(lsb_release --release).split.last
176 linux_version = linux_distro + " " + linux_release
177 kernel_release = `uname -r`
181 if not linux_release.match '^1[234]\.'
182 warn "Arvados requires at least Ubuntu 12.04 (Precise Pangolin)."
183 warn "Your system is Ubuntu #{linux_release}."
186 if linux_release.match '^12' and kernel_release.start_with? '3.2'
187 # Ubuntu Precise ships with a 3.2 kernel and must be upgraded.
188 warn "Your kernel #{kernel_release} must be upgraded to run Docker."
190 warn " sudo apt-get update"
191 warn " sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
196 sudo 'apt-get', 'update'
197 sudo 'apt-get', 'install', "linux-image-extra-#{kernel_release}"
200 # add Docker repository
201 sudo %w(/usr/bin/apt-key adv
202 --keyserver keyserver.ubuntu.com
203 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9)
204 source_file = Tempfile.new('arv')
205 source_file.write("deb http://get.docker.io/ubuntu docker main\n")
207 sudo '/bin/mv', source_file.path, '/etc/apt/sources.list.d/docker.list'
208 sudo %w(/usr/bin/apt-get update)
209 sudo %w(/usr/bin/apt-get install lxc-docker)
211 # Set up for non-root access
212 sudo %w(/usr/sbin/groupadd docker)
213 sudo '/usr/bin/gpasswd', '-a', ENV['USER'], 'docker'
214 sudo %w(/usr/sbin/service docker restart)
217 warn "Must be running a Debian or Ubuntu release in order to run Docker."
223 if __FILE__ == $PROGRAM_NAME
224 options = { :makefile => File.join(File.dirname(__FILE__), 'Makefile') }
225 OptionParser.new do |opts|
226 opts.on('-m', '--makefile MAKEFILE-PATH',
227 'Path to the Makefile used to build Arvados Docker images') do |mk|
228 options[:makefile] = mk