require 'rubygems' require 'restfully' require 'restfully/addons/bonfire' ##Editable parameters #LOCATION = "de-hlrs" LOCATION = "fr-inria" #LOCATION = "uk-epcc" ## EXPERIMENT_NAME = "Build image master" EXPERIMENT_DESCRIPTION = "Build image master for virtual cluster" EXPERIMENT_WALLTIME = 3600 IMAGE_NAME = "BonFIRE Debian Squeeze 2G v3" NEW_IMAGE_NAME = "VirtualClusterMaster-vcocdemo-v0.1" WAN_NAME = "BonFIRE WAN" session = Restfully::Session.new( :configuration_file => "~/.restfully/api.bonfire-project.eu", :cache => false, :gateway => "ssh.fr-inria.bonfire-project.eu", :keys => ["~/.ssh/id_rsa"] ) session.logger.level = Logger::INFO #session.logger.level = Logger::DEBUG experiment = nil begin session.logger.info "Deploying experiment..." experiment = session.root.experiments.submit( :name => EXPERIMENT_NAME, :description => EXPERIMENT_DESCRIPTION + " - " + Time.now.to_s, # :status => "waiting", :walltime => EXPERIMENT_WALLTIME ) location = session.root.locations[:"#{LOCATION}"] session.logger.info "Chosen location is: #{location['name']}" fail "Can't select the machine location" if location.nil? session.logger.info "Deleting previous version" storage = location.storages.find{|s| s["name"] == NEW_IMAGE_NAME} storage.delete unless storage.nil? session.logger.info "Launching machine..." machine = experiment.computes.submit( :name => "machine-experiment#{experiment['id']}", :instance_type => "small", :disk => [{:storage => location.storages.find{|s| s['name'] == IMAGE_NAME}}], :nic => [ {:network => location.networks.find{|n| n['name'] == WAN_NAME}} ], :location => location, :context => {} ) hostname = "#{machine['name']}-#{machine['id']}" session.logger.info "Machine: #{hostname} #{machine['nic'][0]['ip']}" session.logger.info "Starting experiment..." experiment.update(:status => "running") #Build SSH keys #session.logger.info "Buildgin SSH keypair..." #ssh_priv = "/tmp/ssh-#{Random.rand(1000)}" #ssh_public = ssh_priv + ".pub" #`ssh-keygen -f #{ssh_priv} -t rsa -P ""` session.logger.info "Checking if machine is ready..." until [machine].all?{|vm| vm.reload['state'] == 'RUNNING' && vm.ssh.accessible? } do fail "Machine has failed" if [machine].any?{|vm| vm['state'] == 'FAILED'} session.logger.info "Machine is not ready. Waiting..." sleep 20 end ocfs_debconf = "cat << EOF | debconf-set-selections ocfs2-tools ocfs2-tools/idle_timeout select 30000 ocfs2-tools ocfs2-tools/reconnect_delay select 2000 ocfs2-tools ocfs2-tools/init select true ocfs2-tools ocfs2-tools/clustername select ocfs2 ocfs2-tools ocfs2-tools/heartbeat_threshold select 31 ocfs2-tools ocfs2-tools/keepalive_delay select 2000 ocfs2-tools ocfs2-tools/idle_timeout seen true ocfs2-tools ocfs2-tools/reconnect_delay seen true ocfs2-tools ocfs2-tools/init seen true ocfs2-tools ocfs2-tools/clustername seen true ocfs2-tools ocfs2-tools/heartbeat_threshold seen true ocfs2-tools ocfs2-tools/keepalive_delay seen true EOF" session.logger.info "Machine is ready" machine.ssh do |ssh| session.logger.info "Preinstallation..." output = ssh.exec!(ocfs_debconf) session.logger.info output unless output.nil? output = ssh.scp.upload!('killproc.sh', '/root/') session.logger.info output unless output.nil? session.logger.info "Installing software..." output = ssh.exec!("apt-get update apt-get install -y -q python-paramiko apt-get install -y -q drbd8-utils ocfs2-tools nfs-kernel-server apt-get autoclean dpkg-reconfigure --frontend=noninteractive ocfs2-tools apt-get install -y -q ocfs2-tools echo 'source /etc/default/bonfire' >> /root/.bashrc sed -i '2 i\ sleep 5' /etc/rc.local sed -i '2 i\ /root/killproc.sh &' /etc/rc.local sed -i '/^exit/ i\python -u /root/vc/vc-main-init.py /var/log/vc-main-init.log' /etc/rc.local chmod 755 /etc/rc.local chmod u+x /root/killproc.sh") session.logger.info output unless output.nil? session.logger.info "Uploading OGS..." output = ssh.scp.upload!('sge_root.tar.gz', '/root/') session.logger.info output unless output.nil? #session.logger.info "Uploading SSH keys..." #output = ssh.exec!("mkdir -p /root/.ssh") #session.logger.info output unless output.nil? #output = ssh.scp.upload!(ssh_priv, '/root/.ssh/id_rsa') #session.logger.info output unless output.nil? #output = ssh.scp.upload!(ssh_public, '/root/.ssh/id_rsa.pub') #session.logger.info output unless output.nil? #output = ssh.exec!("cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys") #session.logger.info output unless output.nil? session.logger.info "Uploading Virtual Cluster scripts..." output = ssh.exec!("mkdir -p /root/vc") session.logger.info output unless output.nil? Dir.glob("vc/*.py").each do |file| output = ssh.scp.upload!(file, '/root/vc/') session.logger.info output unless output.nil? end end session.logger.warn "Image installation finished" session.logger.warn "Saving image and shutting down" machine.update(:disk => [{:save_as => {:name => NEW_IMAGE_NAME}}]) machine.update(:state => 'SHUTDOWN') until machine.reload['state'] == 'DONE' do session.logger.info "Machine is #{machine['state']}." sleep 20 end experiment.delete session.logger.info "Image built: #{NEW_IMAGE_NAME}" session.logger.warn "Experiment terminated!" rescue Exception => e session.logger.error "#{e.class.name}: #{e.message}" session.logger.error e.backtrace.join("\n") session.logger.warn "Cleaning up in 30 seconds. Hit CTRL-C now to keep your VMs..." sleep 30 experiment.delete unless experiment.nil? end