Module: VirtualMonkey::Command
- Defined in:
- lib/virtualmonkey/command.rb,
lib/virtualmonkey/command/run.rb,
lib/virtualmonkey/command/list.rb,
lib/virtualmonkey/command/clone.rb,
lib/virtualmonkey/command/troop.rb,
lib/virtualmonkey/command/create.rb,
lib/virtualmonkey/command/destroy.rb
Class Method Summary collapse
-
.clone ⇒ Object
monkey clone –deployment name –feature testcase.rb –breakpoint 4 –copies 7.
-
.create ⇒ Object
monkey create –server_template_ids 123,123 –common_inputs blah.json –feature simple.feature –tag unique_name –TBD:filter?.
-
.destroy ⇒ Object
monkey destroy –tag unique_tag.
-
.go ⇒ Object
Parses the initial command string, removing it from ARGV, then runs command.
- .list ⇒ Object
-
.run ⇒ Object
monkey run –feature –tag –only <regex to match on deploy nickname>.
-
.troop ⇒ Object
This command does all the steps create/run/conditionaly destroy.
Class Method Details
.clone ⇒ Object
monkey clone –deployment name –feature testcase.rb –breakpoint 4 –copies 7
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/virtualmonkey/command/clone.rb', line 5 def self.clone = Trollop:: do opt :deployment, "regex string to use for matching deployment", :type => :string, :short => '-d', :required => true opt :feature, "path to feature(s) to run against the deployments", :type => :string opt :breakpoint, "feature file line to stop at", :type => :integer, :short => '-b' opt :copies, "number of copies to make (default is 1)", :type => :integer, :short => '-c' end [:copies] = 1 unless [:copies] > 1 [:no_resume] = true dm = DeploymentMonk.new([:deployment]) if dm.deployments.length > 1 raise "FATAL: Ambiguous Regex; more than one deployment matched /#{[:deployment]}/" elsif dm.deployments.length < 1 raise "FATAL: Ambiguous Regex; no deployment matched /#{[:deployment]}/" end origin = dm.deployments.first do_these ||= [] # clone deployment for i in 1 .. [:copies] new_deploy = origin.clone new_deploy.nickname = "#{origin.nickname}-clone-#{i}" new_deploy.save do_these << new_deploy end # run to breakpoint if [:feature] EM.run { cm = CukeMonk.new cm. = do_these.each do |deploy| cm.run_test(deploy, [:feature]) end watch = EM.add_periodic_timer(10) { if cm.all_done? watch.cancel end cm.watch_and_report } } end end |
.create ⇒ Object
monkey create –server_template_ids 123,123 –common_inputs blah.json –feature simple.feature –tag unique_name –TBD:filter?
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/virtualmonkey/command/create.rb', line 5 def self.create = Trollop:: do opt :server_template_ids, "ServerTemplate ids to use for creating the deployment. Use one ID per server that you would like to be in the deployment. Accepts space separated integers, or one argument per id. Eg. -s 23747 23747", :type => :integers, :required => true, :short => '-s' opt :common_inputs, "Paths to common input json files to load and set on all deployments. Accepts space separated pathnames or one argument per pathname. Eg. -c config/mysql_inputs.json -c config/other_inputs.json", :type => :strings, :required => true, :short => '-c' opt :tag, "Tag to use as nickname prefix for all deployments.", :type => :string, :required => true, :short => '-t' opt :cloud_variables, "Path to json file containing common inputs and variables per cloud. See config/cloud_variables.json.example", :type => :string, :required => true, :short => '-v' opt :no_spot, "Do not use spot instances" end @dm = DeploymentMonk.new([:tag], [:server_template_ids]) @dm.variables_for_cloud = JSON::parse(IO.read([:cloud_variables])) [:common_inputs].each do |cipath| @dm.load_common_inputs(cipath) end @dm.generate_variations() end |
.destroy ⇒ Object
monkey destroy –tag unique_tag
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/virtualmonkey/command/destroy.rb', line 5 def self.destroy = Trollop:: do opt :tag, "Tag to match prefix of the deployments to destroy.", :type => :string, :required => true, :short => '-t' opt :terminate, "Terminate using the specified runner", :type => :string, :required => true, :short => "-r" opt :no_delete, "only terminate, no deletion." opt :yes, "Turn off confirmation for destroy operation" end begin eval("VirtualMonkey::#{[:terminate]}.new('fgasvgreng243o520sdvnsals')") if [:terminate] rescue Exception => e raise e unless e. =~ /Could not find a deployment named/ [:terminate] = "SimpleRunner" if [:terminate] end @dm = DeploymentMonk.new([:tag]) # nicks = @dm.deployments.map &:nickname nicks = @dm.deployments.map { |d| d.nickname } nicks.each { |n| say n } unless [:yes] confirm = ask("Really destroy these #{nicks.length} deployments (y/n)?", lambda { |ans| true if (ans =~ /^[y,Y]{1}/) }) raise "Aborting." unless confirm end global_state_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "test_states") @dm.deployments.each do |deploy| @runner = eval("VirtualMonkey::#{[:terminate]}.new(deploy.nickname)") @runner.behavior(:stop_all, false) state_dir = File.join(global_state_dir, deploy.nickname) if File.directory?(state_dir) puts "Deleting state files for #{deploy.nickname}..." Dir.new(state_dir).each do |state_file| if File.extname(state_file) =~ /((rb)|(feature))/ File.delete(File.join(state_dir, state_file)) end end Dir.rmdir(state_dir) end if @runner.respond_to?(:release_dns) and not [:no_delete] @runner.behavior(:release_dns) end end @dm.destroy_all unless [:no_delete] say "monkey done." end |
.go ⇒ Object
Parses the initial command string, removing it from ARGV, then runs command.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/virtualmonkey/command.rb', line 15 def self.go command = ARGV.shift case command when "create" VirtualMonkey::Command.create when "destroy" VirtualMonkey::Command.destroy when "run" VirtualMonkey::Command.run when "list" VirtualMonkey::Command.list when "troop" VirtualMonkey::Command.troop when "clone" VirtualMonkey::Command.clone when "help" || "--help" || "-h" puts "Help usage: monkey <command> --help" puts "Valid commands for monkey: create, destroy, list, run, troop, clone or help" else STDERR.puts "Invalid command #{command}: You need to specify a command for monkey: create, destroy, list, run, troop, clone or help\n" exit(1) end end |
.list ⇒ Object
3 4 5 6 7 8 |
# File 'lib/virtualmonkey/command/list.rb', line 3 def self.list = Trollop:: do opt :tags, "List deployment set tags", :type => :string, :required => true end DeploymentMonk.new([:tags]).deployments.each { |d| puts d.nickname } end |
.run ⇒ Object
monkey run –feature –tag –only <regex to match on deploy nickname>
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/virtualmonkey/command/run.rb', line 8 def self.run = Trollop:: do opt :feature, "path to feature(s) to run against the deployments", :type => :string, :required => true opt :breakpoint, "feature file line to stop at", :type => :integer, :short => '-b' opt :tag, "Tag to match prefix of the deployments.", :type => :string, :required => true, :short => "-t" opt :only, "regex string to use for subselection matching on deployments. Eg. --only x86_64", :type => :string opt :terminate, "Terminate using the specified runner if feature successfully completes. (No destroy)", :type => :string, :short => "-r" opt :no_resume, "Do not use current test-in-progress, start from scratch", :short => "-n" opt :yes, "Turn off confirmation", :short => "-y" end global_state_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "test_states") begin eval("VirtualMonkey::#{[:terminate]}.new('fgasvgreng243o520sdvnsals')") if [:terminate] rescue Exception => e raise e unless e. =~ /Could not find a deployment named/ [:terminate] = "SimpleRunner" if [:terminate] end EM.run { cm = CukeMonk.new dm = DeploymentMonk.new([:tag]) if [:only] do_these = dm.deployments.select { |d| d.nickname =~ /#{[:only]}/ } else do_these = dm.deployments end unless [:no_resume] temp = do_these.select do |d| File.exist?(File.join(global_state_dir, d.nickname, File.basename([:feature]))) end do_these = temp if temp.length > 0 end cm. = raise "No deployments matched!" unless do_these.length > 0 do_these.each { |d| say d.nickname } unless [:yes] confirm = ask("Run tests on these #{do_these.length} deployments (y/n)?", lambda { |ans| true if (ans =~ /^[y,Y]{1}/) }) raise "Aborting." unless confirm end remaining_jobs = cm.jobs.dup do_these.each do |deploy| cm.run_test(deploy, [:feature]) end watch = EM.add_periodic_timer(10) { cm.watch_and_report if cm.all_done? watch.cancel end if [:terminate] remaining_jobs.each do |job| if job.status == 0 @runner = eval("VirtualMonkey::#{[:terminate]}.new(job.deployment.nickname)") puts "destroying successful deployment: #{@runner.deployment.nickname}" @runner.behavior(:stop_all, false) remaining_jobs.delete(job) end end end } } end |
.troop ⇒ Object
This command does all the steps create/run/conditionaly destroy
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/virtualmonkey/command/troop.rb', line 4 def self.troop = Trollop:: do text "This command performs all the operations of the monkey in one execution. Create/Run/Destroy" opt :file, "troop config, see config/troop/*sample.json for example format", :type => :string, :required => true opt :no_spot, "do not use spot instances" opt :step, "use the troop config file to do either: create, run, or destroy", :type => :string opt :tag, "add an additional tag to the deployments", :type => :string opt :create, "interactive mode: create troop config" opt :mci_override, "list of mcis to use instead of the ones from the server template. expects full hrefs.", :type => :string, :multi => true, :required => false opt :no_delete, "only terminate, no deletion.", :short => "-d" end # PATHs SETUP features_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "features") features_glob = Dir.glob(File.join(features_dir, "**")) features_glob = features_glob.collect { |c| File.basename(c) } config_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "config") cloud_variables_glob = Dir.glob(File.join(config_dir, "cloud_variables", "**")) cloud_variables_glob = cloud_variables_glob.collect { |c| File.basename(c) } common_inputs_glob = Dir.glob(File.join(config_dir, "common_inputs", "**")) common_inputs_glob = common_inputs_glob.collect { |c| File.basename(c) } global_state_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "test_states") [:tag] += "-" if [:tag] [:tag] = "" unless [:tag] # CREATE NEW CONFIG if [:create] troop_config = {} troop_config[:tag] = ask("What tag to use for creating the deployments?") troop_config[:server_template_ids] = ask("What Server Template ids would you like to use to create the deployments (comma delimited)?").split(",") troop_config[:server_template_ids].each {|st| st.strip!} troop_config[:runner] = choose do || .prompt = "What kind of deployment is this (runner type)?" .choice("MysqlToolboxRunner") .choice("MysqlRunner") .choice("SimpleRunner") end troop_config[:cloud_variables] = choose do || .prompt = "Which cloud_variables config file?" .index = :number .choices(*cloud_variables_glob) end troop_config[:common_inputs] = choose do || .prompt = "Which common_inputs config file?" .index = :number .choices(*common_inputs_glob) end troop_config[:feature] = choose do || .prompt = "Which feature file?" .index = :number .choices(*features_glob) end write_out = troop_config.to_json( :indent => " ", :object_nl => "\n", :array_nl => "\n" ) File.open([:file], "w") { |f| f.write(write_out) } say("created config file #{[:file]}") say("Done.") else # Execute Main config = JSON::parse(IO.read([:file])) [:step] = "all" unless [:step] tag = [:tag] + config['tag'] # CREATE PHASE if [:step] =~ /((all)|(create))/ @dm = DeploymentMonk.new(tag, config['server_template_ids']) @dm.variables_for_cloud = JSON::parse(IO.read(File.join(config_dir, "cloud_variables", config['cloud_variables']))) config['common_inputs'].each do |cipath| @dm.load_common_inputs(File.join(config_dir, "common_inputs", cipath)) end @dm.generate_variations() end # RUN PHASE if [:step] =~ /((all)|(run))/ @dm = DeploymentMonk.new(tag) if [:step] =~ /run/ EM.run { @cm = CukeMonk.new @cm. = {} remaining_jobs = @cm.jobs.dup @dm.deployments.each do |deploy| @cm.run_test(deploy, File.join(features_dir, config['feature'])) end watch = EM.add_periodic_timer(10) { @cm.watch_and_report if @cm.all_done? watch.cancel end remaining_jobs.each do |job| # destroy on success only (keep failed deploys) if job.status == 0 and [:step] =~ /all/ runner = eval("VirtualMonkey::#{config['runner']}.new(job.deployment.nickname)") puts "destroying successful deployment: #{runner.deployment.nickname}" runner.behavior(:stop_all, false) runner.deployment.destroy unless [:no_delete] remaining_jobs.delete(job) if runner.respond_to?(:release_dns) and not [:no_delete] runner.behavior(:release_dns) end end end } } end if [:step] =~ /destroy/ @dm = DeploymentMonk.new(tag) @dm.deployments.each do |deploy| runner = eval("VirtualMonkey::#{config['runner']}.new(deploy.nickname)") runner.behavior(:stop_all, false) state_dir = File.join(global_state_dir, deploy.nickname) if File.directory?(state_dir) puts "Deleting state files for #{deploy.nickname}..." Dir.new(state_dir).each do |state_file| if File.extname(state_file) =~ /((rb)|(feature))/ File.delete(File.join(state_dir, state_file)) end end Dir.rmdir(state_dir) end if runner.respond_to?(:release_dns) and not [:no_delete] runner.behavior(:release_dns) end end @dm.destroy_all unless [:no_delete] end end puts "Troop done." end |