RUN apt-get update && \
apt-get -q -y install procps postgresql postgresql-server-dev-9.1 apache2 slurm-llnl munge \
supervisor sudo libwww-perl libio-socket-ssl-perl libcrypt-ssleay-perl \
- libjson-perl && \
+ libjson-perl cron && \
git clone --bare git://github.com/curoverse/arvados.git /var/cache/git/arvados.git
ADD munge.key /etc/munge/
ADD keep_server_0.json /root/
ADD keep_server_1.json /root/
+# Set up update-gitolite.rb
+RUN mkdir /usr/local/arvados/config -p
+ADD generated/arvados-clients.yml /usr/local/arvados/config/
+ADD update-gitolite.rb /usr/local/arvados/
+
# Supervisor.
ADD supervisor.conf /etc/supervisor/conf.d/arvados.conf
ADD ssh.sh /usr/local/bin/ssh.sh
ADD generated/setup.sh /usr/local/bin/setup.sh
+ADD setup-gitolite.sh /usr/local/bin/setup-gitolite.sh
ADD crunch-dispatch-run.sh /usr/local/bin/crunch-dispatch-run.sh
ADD apache2_foreground.sh /etc/apache2/foreground.sh
--- /dev/null
+#!/bin/bash
+
+ssh-keygen -q -N '' -t rsa -f /root/.ssh/id_rsa
+
+useradd git
+mkdir /home/git
+
+# Set up gitolite repository
+cp ~root/.ssh/id_rsa.pub ~git/root-authorized_keys.pub
+chown git:git /home/git -R
+su - git -c "mkdir -p ~/bin"
+
+su - git -c "git clone git://github.com/sitaramc/gitolite"
+su - git -c "gitolite/install -ln ~/bin"
+su - git -c "PATH=/home/git/bin:$PATH gitolite setup -pk ~git/root-authorized_keys.pub"
+
+# Now set up the gitolite repo(s) we use
+mkdir -p /usr/local/arvados/gitolite-tmp/
+# Make ssh store the host key
+ssh -o "StrictHostKeyChecking no" git@api info
+# Now check out the tree
+git clone git@api:gitolite-admin.git /usr/local/arvados/gitolite-tmp/gitolite-admin/
+cd /usr/local/arvados/gitolite-tmp/gitolite-admin
+mkdir keydir/arvados
+mkdir conf/admin
+mkdir conf/auto
+echo "
+
+@arvados_git_user = arvados_git_user
+
+repo @all
+ RW+ = @arvados_git_user
+
+" > conf/admin/arvados.conf
+echo '
+include "auto/*.conf"
+include "admin/*.conf"
+' >> conf/gitolite.conf
+
+#su - git -c "ssh-keygen -t rsa"
+cp /root/.ssh/id_rsa.pub keydir/arvados/arvados_git_user.pub
+# Replace the 'root' key with the user key, just in case
+cp /root/.ssh/authorized_keys keydir/root-authorized_keys.pub
+# But also make sure we have the root key installed so it can access all keys
+git add keydir/root-authorized_keys.pub
+git add keydir/arvados/arvados_git_user.pub
+git add conf/admin/arvados.conf
+git add keydir/arvados/
+git add conf/gitolite.conf
+git commit -a -m 'git server setup'
+git push
+
+echo "ARVADOS_API_HOST_INSECURE=yes" > /etc/cron.d/gitolite-update
+echo "*/5 * * * * root /bin/bash -c 'source /etc/profile.d/rvm.sh && /usr/local/arvados/update-gitolite.rb production'" >> /etc/cron.d/gitolite-update
+
--- /dev/null
+#!/usr/bin/env ruby
+
+###################################################################
+# THIS FILE IS MANAGED BY PUPPET -- CHANGES WILL BE OVERWRITTEN #
+###################################################################
+
+require 'rubygems'
+require 'pp'
+require 'arvados'
+require 'active_support/all'
+
+# This script does the actual gitolite config management on disk.
+#
+# Ward Vandewege <ward@curoverse.com>
+
+# Default is development
+production = ARGV[0] == "production"
+
+ENV["RAILS_ENV"] = "development"
+ENV["RAILS_ENV"] = "production" if production
+
+DEBUG = 1
+
+# load and merge in the environment-specific application config info
+# if present, overriding base config parameters as specified
+path = File.dirname(__FILE__) + '/config/arvados-clients.yml'
+if File.exists?(path) then
+ cp_config = YAML.load_file(path)[ENV['RAILS_ENV']]
+else
+ puts "Please create a\n " + File.dirname(__FILE__) + "/config/arvados-clients.yml\n file"
+ exit 1
+end
+
+gitolite_url = cp_config['gitolite_url']
+gitolite_tmp = cp_config['gitolite_tmp']
+
+gitolite_admin = File.join(File.expand_path(File.dirname(__FILE__)) + '/' + gitolite_tmp + '/gitolite-admin')
+
+ENV['ARVADOS_API_HOST'] = cp_config['arvados_api_host']
+ENV['ARVADOS_API_TOKEN'] = cp_config['arvados_api_token']
+
+keys = ''
+
+seen = Hash.new
+
+def ensure_repo(name,permissions,user_keys,gitolite_admin)
+ tmp = ''
+ # Just in case...
+ name.gsub!(/[^a-z0-9]/i,'')
+
+ keys = Hash.new()
+
+ user_keys.each do |uuid,p|
+ p.each do |k|
+ next if k[:public_key].nil?
+ keys[uuid] = Array.new() if not keys.key?(uuid)
+
+ key = k[:public_key]
+ # Handle putty-style ssh public keys
+ key.sub!(/^(Comment: "r[^\n]*\n)(.*)$/m,'ssh-rsa \2 \1')
+ key.sub!(/^(Comment: "d[^\n]*\n)(.*)$/m,'ssh-dss \2 \1')
+ key.gsub!(/\n/,'')
+ key.strip
+
+ keys[uuid].push(key)
+ end
+ end
+
+ cf = gitolite_admin + '/conf/auto/' + name + '.conf'
+
+ conf = "\nrepo #{name}\n"
+
+ commit = false
+
+ seen = {}
+ permissions.sort.each do |uuid,v|
+ conf += "\t#{v[:gitolite_permissions]}\t= #{uuid.to_s}\n"
+
+ count = 0
+ keys.include?(uuid) and keys[uuid].each do |v|
+ kf = gitolite_admin + '/keydir/arvados/' + uuid.to_s + "@#{count}.pub"
+ seen[kf] = true
+ if !File.exists?(kf) or IO::read(kf) != v then
+ commit = true
+ f = File.new(kf + ".tmp",'w')
+ f.write(v)
+ f.close()
+ # File.rename will overwrite the destination file if it exists
+ File.rename(kf + ".tmp",kf);
+ end
+ count += 1
+ end
+ end
+
+ if !File.exists?(cf) or IO::read(cf) != conf then
+ commit = true
+ f = File.new(cf + ".tmp",'w')
+ f.write(conf)
+ f.close()
+ # this is about as atomic as we can make the replacement of the file...
+ File.unlink(cf) if File.exists?(cf)
+ File.rename(cf + ".tmp",cf);
+ end
+
+ return commit,seen
+end
+
+begin
+
+ pwd = Dir.pwd
+ # Get our local gitolite-admin repo up to snuff
+ if not File.exists?(File.dirname(__FILE__) + '/' + gitolite_tmp) then
+ Dir.mkdir(File.join(File.dirname(__FILE__) + '/' + gitolite_tmp), 0700)
+ end
+ if not File.exists?(gitolite_admin) then
+ Dir.chdir(File.join(File.dirname(__FILE__) + '/' + gitolite_tmp))
+ `git clone #{gitolite_url}`
+ else
+ Dir.chdir(gitolite_admin)
+ `git pull`
+ end
+ Dir.chdir(pwd)
+
+ arv = Arvados.new( { :suppress_ssl_warnings => false } )
+
+ permissions = arv.repository.get_all_permissions
+
+ repos = permissions[:repositories]
+ user_keys = permissions[:user_keys]
+
+ @commit = false
+
+ @seen = {}
+
+ repos.each do |r|
+ next if r[:name].nil?
+ (@c,@s) = ensure_repo(r[:name],r[:user_permissions],user_keys,gitolite_admin)
+ @seen.merge!(@s)
+ @commit = true if @c
+ end
+
+ # Clean up public key files that should not be present
+ Dir.glob(gitolite_admin + '/keydir/arvados/*.pub') do |key_file|
+ next if key_file =~ /arvados_git_user.pub$/
+ next if @seen.has_key?(key_file)
+ puts "Extra file #{key_file}"
+ @commit = true
+ Dir.chdir(gitolite_admin)
+ key_file.gsub!(/^#{gitolite_admin}\//,'')
+ `git rm #{key_file}`
+ end
+
+ if @commit then
+ message = "#{Time.now().to_s}: update from API"
+ Dir.chdir(gitolite_admin)
+ `git add --all`
+ `git commit -m '#{message}'`
+ `git push`
+ end
+
+rescue Exception => bang
+ puts "Error: " + bang.to_s
+ puts bang.backtrace.join("\n")
+ exit 1
+end
+