--- virt-cluster/build-master.rb 2012/08/30 10:01:42 8 +++ virt-cluster/build-master.rb 2012/08/31 10:40:38 10 @@ -1,160 +1,173 @@ -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" -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 - -NEW_IMAGE_NAME = "VirtualClusterMaster-#{session.config[:username]}-v0.1" - -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 +# +# BonFIRE Virtual Clusters on Federated Clouds Demonstration Kit +# +# Copyright (c) Fundacion Centro Tecnologico de Supercomputacion de Galicia 2012 +# +# License GPL Version 3 +# +# The research leading to these results has received funding from +# the European Community's Seventh Framework Programme (FP7/2007-2013) +# under agreement number 257386 +# +# This software is provided with ABSOLUTELY NO WARRANTY +# +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" +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 + +NEW_IMAGE_NAME = "VirtualClusterMaster-#{session.config[:username]}-v0.1" + +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