elzar 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +46 -83
- data/README.md +19 -17
- data/USAGE.md +257 -0
- data/bin/elzar +94 -0
- data/chef/site-cookbooks/ruby/metadata.rb +3 -1
- data/chef/site-cookbooks/ruby/recipes/default.rb +1 -0
- data/chef/site-cookbooks/ruby/recipes/path.rb +17 -0
- data/elzar.gemspec +4 -0
- data/lib/elzar.rb +5 -1
- data/lib/elzar/assistant.rb +82 -70
- data/lib/elzar/aws_config.rb +46 -0
- data/lib/elzar/cli.rb +143 -0
- data/lib/elzar/compute.rb +52 -0
- data/lib/elzar/core_ext/hash.rb +18 -0
- data/lib/elzar/fog.rb +53 -0
- data/lib/elzar/ssh_key_locator.rb +37 -0
- data/lib/elzar/templates/Gemfile +4 -4
- data/lib/elzar/templates/Vagrantfile.erb +1 -1
- data/lib/elzar/templates/aws_config.private.yml +13 -0
- data/lib/elzar/templates/aws_config.yml +6 -0
- data/lib/elzar/templates/data_bags/deploy/authorized_keys.json +4 -5
- data/lib/elzar/templates/dna/rails.json +15 -0
- data/lib/elzar/templates/gitignore +1 -0
- data/lib/elzar/version.rb +1 -1
- data/script/ci_nightly +14 -0
- data/spec/fixtures/rails_integration_template/add_root_user.rb +9 -0
- data/spec/fixtures/rails_integration_template/database.yml +7 -0
- data/spec/fixtures/rails_integration_template/deploy.rb +11 -0
- data/spec/fixtures/rails_integration_template/template.rb +22 -0
- data/spec/integration/rails_spec.rb +190 -0
- data/spec/lib/elzar/assistant_spec.rb +30 -0
- data/spec/lib/elzar/aws_config_spec.rb +84 -0
- data/spec/lib/elzar/ssh_key_locator_spec.rb +51 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/shell_interaction_helpers.rb +33 -0
- metadata +107 -7
- data/lib/elzar/chef_dna.rb +0 -48
- data/lib/elzar/templates/dna.json +0 -25
- data/spec/chef_dna_spec.rb +0 -58
data/bin/elzar
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
begin # XXX: Remove this begin/rescue before distributing your app
|
4
|
+
require 'elzar/cli'
|
5
|
+
rescue LoadError
|
6
|
+
STDERR.puts "In development, you need to use `bundle exec bin/elzar` to run your app"
|
7
|
+
STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
|
8
|
+
STDERR.puts "Feel free to remove this message from bin/elzar now"
|
9
|
+
exit 64
|
10
|
+
end
|
11
|
+
|
12
|
+
include GLI::App
|
13
|
+
|
14
|
+
program_desc 'Describe your application here'
|
15
|
+
|
16
|
+
version Elzar::VERSION
|
17
|
+
|
18
|
+
desc 'Sets up default provisioning skeleton'
|
19
|
+
command :init do |c|
|
20
|
+
c.flag :dna,
|
21
|
+
:default_value => 'rails',
|
22
|
+
:arg_name => 'dna',
|
23
|
+
:must_match => %w[rails], # TODO Dynamically determine the list of available DNAs (e.g., clojure, etc.)
|
24
|
+
:desc => 'The application stack you wish to deploy'
|
25
|
+
|
26
|
+
c.action do |global_options,options,args|
|
27
|
+
Elzar::Cli::Init.run(global_options.merge(options))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Spins up a new EC2 instance ready for cooking'
|
32
|
+
arg_name 'instance_name' # TODO raise error if arg not given
|
33
|
+
command :preheat do |c|
|
34
|
+
c.flag :aws_config_dir,
|
35
|
+
:default_value => Elzar::AwsConfig::DEFAULT_CONFIG_DIR,
|
36
|
+
:arg_name => 'aws_config_dir',
|
37
|
+
:desc => "The directory containing your AWS config files"
|
38
|
+
|
39
|
+
c.action do |global_options,options,args|
|
40
|
+
instance_name = args.first
|
41
|
+
Elzar::Cli::Preheat.run(instance_name, global_options.merge(options))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'Converges and runs recipes on given instance'
|
46
|
+
arg_name 'instance_id' # TODO raise error if arg not given
|
47
|
+
command :cook do |c|
|
48
|
+
c.flag :aws_config_dir,
|
49
|
+
:default_value => Elzar::AwsConfig::DEFAULT_CONFIG_DIR,
|
50
|
+
:arg_name => 'aws_config_dir',
|
51
|
+
:desc => "The directory containing your AWS config files"
|
52
|
+
|
53
|
+
c.action do |global_options,options,args|
|
54
|
+
instance_id = args.first
|
55
|
+
Elzar::Cli::Cook.run(instance_id, global_options.merge(options))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'Destroys the given EC2 instance'
|
60
|
+
arg_name 'instance_id' # TODO raise error if arg not given
|
61
|
+
command :destroy do |c|
|
62
|
+
c.flag :aws_config_dir,
|
63
|
+
:default_value => Elzar::AwsConfig::DEFAULT_CONFIG_DIR,
|
64
|
+
:arg_name => 'aws_config_dir',
|
65
|
+
:desc => "The directory containing your AWS config files"
|
66
|
+
|
67
|
+
c.action do |global_options,options,args|
|
68
|
+
instance_id = args.first
|
69
|
+
Elzar::Cli::Destroy.run(instance_id, global_options.merge(options))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
pre do |global,command,options,args|
|
74
|
+
# Pre logic here
|
75
|
+
# Return true to proceed; false to abourt and not call the
|
76
|
+
# chosen command
|
77
|
+
# Use skips_pre before a command to skip this block
|
78
|
+
# on that command only
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
post do |global,command,options,args|
|
83
|
+
# Post logic here
|
84
|
+
# Use skips_post before a command to skip this
|
85
|
+
# block on that command only
|
86
|
+
end
|
87
|
+
|
88
|
+
on_error do |exception|
|
89
|
+
# Error logic here
|
90
|
+
# return false to skip default error handling
|
91
|
+
true
|
92
|
+
end
|
93
|
+
|
94
|
+
exit run(ARGV)
|
@@ -1,6 +1,8 @@
|
|
1
1
|
maintainer "Relevance"
|
2
2
|
maintainer_email "opfor@thinkrelevance.com"
|
3
3
|
license "All rights reserved"
|
4
|
-
description "Installs/Configures
|
4
|
+
description "Installs/Configures Ruby"
|
5
|
+
recipe "ruby", "Installs and configures Ruby"
|
6
|
+
recipe "ruby::path", "Adds Ruby to every user's PATH"
|
5
7
|
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
|
6
8
|
version "0.0.1"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: ruby
|
3
|
+
# Recipe:: path
|
4
|
+
#
|
5
|
+
# Copyright 2012, Relevance
|
6
|
+
#
|
7
|
+
# All rights reserved - Do Not Redistribute
|
8
|
+
|
9
|
+
bash "Add ruby to each user's PATH" do
|
10
|
+
code <<-SH
|
11
|
+
for f in `ls /home/*/.bashrc`; do
|
12
|
+
if ! grep -q "#{node[:ruby][:install_path]}" "$f"; then
|
13
|
+
echo -e '\\nexport PATH="#{node[:ruby][:install_path]}/bin:$PATH"\\n' | sudo tee -a "$f"
|
14
|
+
fi
|
15
|
+
done
|
16
|
+
SH
|
17
|
+
end
|
data/elzar.gemspec
CHANGED
@@ -15,8 +15,12 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
|
18
|
+
s.add_dependency 'gli', '~> 2.0.0'
|
18
19
|
s.add_dependency 'multi_json', '~> 1.3.0'
|
20
|
+
s.add_dependency 'fog', '~> 1.5.0'
|
21
|
+
s.add_dependency 'slushy', '~> 0.1.3'
|
19
22
|
s.add_development_dependency 'rake', '~> 0.9.2.2'
|
20
23
|
s.add_development_dependency 'rspec'
|
24
|
+
s.add_development_dependency 'bahia'
|
21
25
|
s.add_development_dependency 'bundler'
|
22
26
|
end
|
data/lib/elzar.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'elzar/version'
|
2
2
|
require 'elzar/template'
|
3
3
|
require 'elzar/assistant'
|
4
|
+
require 'elzar/aws_config'
|
5
|
+
require 'elzar/compute'
|
6
|
+
|
7
|
+
require 'elzar/core_ext/hash'
|
4
8
|
|
5
9
|
module Elzar
|
6
10
|
ROOT_DIR = File.expand_path File.dirname(__FILE__) + '/../'
|
@@ -14,7 +18,7 @@ module Elzar
|
|
14
18
|
end
|
15
19
|
|
16
20
|
def self.create_provision_directory(destination, options={})
|
17
|
-
Assistant.create_user_provision_dir destination.to_s, options
|
21
|
+
Assistant.create_user_provision_dir destination.to_s, options
|
18
22
|
Assistant.generate_files destination.to_s, options
|
19
23
|
end
|
20
24
|
|
data/lib/elzar/assistant.rb
CHANGED
@@ -1,96 +1,108 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'tmpdir'
|
3
|
-
require 'elzar/chef_dna'
|
4
3
|
|
5
4
|
module Elzar
|
6
5
|
module Assistant
|
7
6
|
ELZAR_DIR = 'elzar'
|
8
7
|
CHEF_SOLO_DIR = '/tmp/chef-solo'
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
"
|
13
|
-
Template.generate 'Vagrantfile', dest, :vm_host_name => vm_host_name,
|
14
|
-
:cookbooks_path => Elzar::COOKBOOK_DIRS, :local => options[:local]
|
15
|
-
if options[:local]
|
16
|
-
generate_local_files dest
|
17
|
-
else
|
18
|
-
require 'multi_json'
|
19
|
-
generate_user_files dest, options
|
9
|
+
class InvalidDnaError < StandardError
|
10
|
+
def initialize(line, line_number)
|
11
|
+
super "Invalid configuration in dna.json:#{line_number} - #{line.strip}"
|
20
12
|
end
|
21
13
|
end
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
15
|
+
class << self
|
16
|
+
def generate_files(dest, options={})
|
17
|
+
vm_host_name = options[:app_name] ?
|
18
|
+
"#{options[:app_name].gsub('_','-')}.local" : "elzar.thinkrelevance.com"
|
19
|
+
Template.generate 'Vagrantfile', dest, :vm_host_name => vm_host_name,
|
20
|
+
:cookbooks_path => Elzar::COOKBOOK_DIRS, :local => options[:local]
|
21
|
+
if options[:local]
|
22
|
+
generate_local_files dest
|
23
|
+
else
|
24
|
+
require 'multi_json'
|
25
|
+
generate_user_files dest, options
|
26
|
+
end
|
27
|
+
end
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
elzar_dir = "#{dest}/#{ELZAR_DIR}"
|
38
|
-
FileUtils.mkdir_p elzar_dir
|
39
|
-
|
40
|
-
generate_solo_rb dest, Elzar::COOKBOOK_DIRS.map {|dir| "#{CHEF_SOLO_DIR}/#{ELZAR_DIR}/#{dir}" }
|
41
|
-
cp_r Elzar::ROLES_DIR, dest
|
42
|
-
cp_r "#{Elzar::CHEF_DIR}/cookbooks", elzar_dir
|
43
|
-
cp_r "#{Elzar::CHEF_DIR}/site-cookbooks", elzar_dir
|
44
|
-
# merges user provision with elzar's provision
|
45
|
-
cp_r "#{user_dir}/.", dest
|
46
|
-
dest
|
47
|
-
end
|
29
|
+
def create_user_provision_dir(dest, options={})
|
30
|
+
dna = options[:dna] || 'rails' # TODO be better than this
|
48
31
|
|
49
|
-
|
32
|
+
FileUtils.mkdir_p dest
|
33
|
+
cp "#{Elzar.templates_dir}/gitignore", "#{dest}/.gitignore"
|
34
|
+
cp "#{Elzar.templates_dir}/.rvmrc", dest
|
35
|
+
cp "#{Elzar.templates_dir}/aws_config.yml", dest
|
36
|
+
cp "#{Elzar.templates_dir}/aws_config.private.yml", dest
|
37
|
+
cp "#{Elzar.templates_dir}/dna/#{dna}.json", "#{dest}/dna.json"
|
38
|
+
cp "#{Elzar.templates_dir}/Gemfile", dest
|
39
|
+
cp "#{Elzar.templates_dir}/README.md", dest
|
40
|
+
cp "#{Elzar.templates_dir}/upgrade-chef.sh", dest
|
41
|
+
cp_r "#{Elzar.templates_dir}/data_bags", dest
|
42
|
+
cp_r "#{Elzar.templates_dir}/script", dest
|
43
|
+
cp_r "#{Elzar.templates_dir}/.chef", dest
|
44
|
+
end
|
50
45
|
|
51
|
-
|
52
|
-
|
53
|
-
cp_r Elzar::ROLES_DIR, dest
|
54
|
-
cp_r "#{Elzar::CHEF_DIR}/cookbooks", dest
|
55
|
-
cp_r "#{Elzar::CHEF_DIR}/site-cookbooks", dest
|
56
|
-
end
|
46
|
+
def merge_and_create_temp_directory(user_dir)
|
47
|
+
validate_dna! "#{user_dir}/dna.json"
|
57
48
|
|
58
|
-
|
59
|
-
|
60
|
-
|
49
|
+
dest = Dir.mktmpdir
|
50
|
+
elzar_dir = "#{dest}/#{ELZAR_DIR}"
|
51
|
+
FileUtils.mkdir_p elzar_dir
|
52
|
+
|
53
|
+
generate_solo_rb dest, Elzar::COOKBOOK_DIRS.map {|dir| "#{CHEF_SOLO_DIR}/#{ELZAR_DIR}/#{dir}" }
|
54
|
+
cp_r Elzar::ROLES_DIR, dest
|
55
|
+
cp_r "#{Elzar::CHEF_DIR}/cookbooks", elzar_dir
|
56
|
+
cp_r "#{Elzar::CHEF_DIR}/site-cookbooks", elzar_dir
|
57
|
+
# merges user provision with elzar's provision
|
58
|
+
cp_r "#{user_dir}/.", dest
|
59
|
+
dest
|
61
60
|
end
|
62
|
-
|
63
|
-
|
61
|
+
|
62
|
+
def validate_dna!(dna_file_path)
|
63
|
+
lines = File.readlines(dna_file_path)
|
64
|
+
lines.each_with_index do |line, line_number|
|
65
|
+
raise InvalidDnaError.new(line, line_number + 1) if line.match(/TODO/)
|
66
|
+
end
|
64
67
|
end
|
65
|
-
end
|
66
68
|
|
67
|
-
|
68
|
-
dirs = Elzar::COOKBOOK_DIRS.map {|dir| "#{CHEF_SOLO_DIR}/#{dir}" }
|
69
|
-
Template.generate "solo.rb", dest, :cookbook_path => dirs + additional,
|
70
|
-
:chef_solo_dir => CHEF_SOLO_DIR
|
71
|
-
end
|
69
|
+
private
|
72
70
|
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def generate_local_files(dest)
|
72
|
+
generate_solo_rb dest
|
73
|
+
cp_r Elzar::ROLES_DIR, dest
|
74
|
+
cp_r "#{Elzar::CHEF_DIR}/cookbooks", dest
|
75
|
+
cp_r "#{Elzar::CHEF_DIR}/site-cookbooks", dest
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
def generate_user_files(dest, options={})
|
79
|
+
if options[:authorized_keys]
|
80
|
+
create_authorized_key_data_bag(options[:authorized_keys], dest)
|
81
|
+
end
|
82
|
+
end
|
80
83
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
84
|
+
def generate_solo_rb(dest, additional=[])
|
85
|
+
dirs = Elzar::COOKBOOK_DIRS.map {|dir| "#{CHEF_SOLO_DIR}/#{dir}" }
|
86
|
+
Template.generate "solo.rb", dest, :cookbook_path => dirs + additional,
|
87
|
+
:chef_solo_dir => CHEF_SOLO_DIR
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
def cp(*args)
|
91
|
+
FileUtils.cp(*args)
|
92
|
+
end
|
93
|
+
|
94
|
+
def cp_r(*args)
|
95
|
+
FileUtils.cp_r(*args)
|
96
|
+
end
|
97
|
+
|
98
|
+
def create_authorized_key_data_bag(authorized_keys, dest)
|
99
|
+
data_bag_dir = "#{dest}/data_bags/deploy"
|
100
|
+
FileUtils.mkdir_p data_bag_dir
|
101
|
+
File.open("#{data_bag_dir}/authorized_keys.json", 'w+') do |f|
|
102
|
+
f.write MultiJson.dump("id" => "authorized_keys", "keys" => authorized_keys)
|
103
|
+
end
|
93
104
|
end
|
94
105
|
end
|
106
|
+
|
95
107
|
end
|
96
108
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Elzar
|
5
|
+
module AwsConfig
|
6
|
+
|
7
|
+
DEFAULT_CONFIG_DIR = 'provision/'
|
8
|
+
CONFIG_FILE = 'aws_config.yml'
|
9
|
+
PRIVATE_CONFIG_FILE = 'aws_config.private.yml'
|
10
|
+
|
11
|
+
class ConfigFileNotFound < StandardError
|
12
|
+
def initialize(file)
|
13
|
+
super "Unable to locate config file: #{file.to_path}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def load_configs(config_directory = nil)
|
19
|
+
config_directory ||= DEFAULT_CONFIG_DIR
|
20
|
+
|
21
|
+
config_file, private_config_file = find_config_files(config_directory)
|
22
|
+
read_and_merge_config_files(config_file, private_config_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def find_config_files(config_directory)
|
28
|
+
dir = Pathname.new config_directory
|
29
|
+
config, private_config = dir.join(CONFIG_FILE), dir.join(PRIVATE_CONFIG_FILE)
|
30
|
+
raise_error_unless_files_exist! config, private_config
|
31
|
+
|
32
|
+
[config, private_config]
|
33
|
+
end
|
34
|
+
|
35
|
+
def read_and_merge_config_files(base_file, other_file)
|
36
|
+
base, other = YAML.load(base_file.read), YAML.load(other_file.read)
|
37
|
+
base.deep_merge(other)
|
38
|
+
end
|
39
|
+
|
40
|
+
def raise_error_unless_files_exist!(*files)
|
41
|
+
files.each { |f| raise ConfigFileNotFound.new(f) unless f.exist? }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/lib/elzar/cli.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'elzar'
|
2
|
+
require 'elzar/ssh_key_locator'
|
3
|
+
|
4
|
+
module Elzar
|
5
|
+
module Cli
|
6
|
+
class MissingArgumentsError < StandardError
|
7
|
+
def initialize(cmd, arguments)
|
8
|
+
super "Required arguments missing (#{arguments.join(', ')})." \
|
9
|
+
" Run `elzar help #{cmd}` for more information."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Runner
|
14
|
+
def self.run(*args)
|
15
|
+
runner = new(*args)
|
16
|
+
runner.require_arguments!
|
17
|
+
runner.run
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.required_argument(*arg_names)
|
21
|
+
@required_arguments ||= []
|
22
|
+
@required_arguments += arg_names
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.required_arguments
|
26
|
+
@required_arguments || []
|
27
|
+
end
|
28
|
+
|
29
|
+
def require_arguments!
|
30
|
+
missing_arguments = self.class.required_arguments.select do |arg|
|
31
|
+
arg_value = self.instance_variable_get(:"@#{arg}")
|
32
|
+
arg_value.to_s.strip.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
raise MissingArgumentsError.new(cmd, missing_arguments) unless missing_arguments.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def notify(msg)
|
41
|
+
# TODO chop off only initial indentation level
|
42
|
+
puts msg.gsub(/^\s+/,'')
|
43
|
+
end
|
44
|
+
|
45
|
+
def aws_config
|
46
|
+
Elzar::AwsConfig.load_configs @aws_config_dir
|
47
|
+
end
|
48
|
+
|
49
|
+
def cmd
|
50
|
+
self.class.name.split('::').last.downcase
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class Init < Runner
|
57
|
+
attr_reader :authorized_keys, :dna
|
58
|
+
|
59
|
+
def initialize(options = {})
|
60
|
+
@dna = options[:dna]
|
61
|
+
end
|
62
|
+
|
63
|
+
def run
|
64
|
+
Elzar.create_provision_directory 'provision', provisioning_options
|
65
|
+
notify <<-MSG
|
66
|
+
Created provision/ directory.
|
67
|
+
!!! You must go edit provision/dna.json to meet your app's needs !!!
|
68
|
+
MSG
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def provisioning_options
|
74
|
+
{
|
75
|
+
:authorized_keys => find_ssh_keys,
|
76
|
+
:dna => dna
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def find_ssh_keys
|
81
|
+
Elzar::SshKeyLocator.find_local_keys
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class Preheat < Runner
|
86
|
+
attr_reader :instance_name
|
87
|
+
|
88
|
+
required_argument :instance_name
|
89
|
+
|
90
|
+
def initialize(instance_name, options = {})
|
91
|
+
@instance_name = instance_name
|
92
|
+
@aws_config_dir = options[:aws_config_dir]
|
93
|
+
end
|
94
|
+
|
95
|
+
def run
|
96
|
+
notify "Provisioning an instance..."
|
97
|
+
instance_id, instance_ip = Elzar::Compute.provision_and_bootstrap!(instance_name, aws_config)
|
98
|
+
notify <<-MSG
|
99
|
+
Finished provisioning server
|
100
|
+
Instance ID: #{instance_id}
|
101
|
+
Instance IP: #{instance_ip}
|
102
|
+
MSG
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class Cook < Runner
|
107
|
+
attr_reader :instance_id
|
108
|
+
|
109
|
+
required_argument :instance_id
|
110
|
+
|
111
|
+
def initialize(instance_id, options = {})
|
112
|
+
@instance_id = instance_id
|
113
|
+
@aws_config_dir = options[:aws_config_dir]
|
114
|
+
end
|
115
|
+
|
116
|
+
def run
|
117
|
+
notify "Cooking..."
|
118
|
+
inst_id, inst_ip = Elzar::Compute.converge!(instance_id, aws_config)
|
119
|
+
notify <<-MSG
|
120
|
+
Finished cooking
|
121
|
+
Instance ID: #{inst_id}
|
122
|
+
Instance IP: #{inst_ip}
|
123
|
+
MSG
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class Destroy < Runner
|
128
|
+
attr_reader :instance_id
|
129
|
+
|
130
|
+
required_argument :instance_id
|
131
|
+
|
132
|
+
def initialize(instance_id, options = {})
|
133
|
+
@instance_id = instance_id
|
134
|
+
@aws_config_dir = options[:aws_config_dir]
|
135
|
+
end
|
136
|
+
|
137
|
+
def run
|
138
|
+
Elzar::Compute.destroy!(instance_id, aws_config)
|
139
|
+
notify "Destroyed instance #{instance_id}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|