mccloud 0.0.1

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.
Files changed (50) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +4 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +74 -0
  5. data/README.md +123 -0
  6. data/Rakefile +5 -0
  7. data/bin/mccloud +116 -0
  8. data/lib/mccloud.rb +2 -0
  9. data/lib/mccloud/command/boot.rb +12 -0
  10. data/lib/mccloud/command/bootstrap.rb +31 -0
  11. data/lib/mccloud/command/command.rb +21 -0
  12. data/lib/mccloud/command/destroy.rb +19 -0
  13. data/lib/mccloud/command/halt.rb +19 -0
  14. data/lib/mccloud/command/init.rb +7 -0
  15. data/lib/mccloud/command/multi.rb +53 -0
  16. data/lib/mccloud/command/provision.rb +28 -0
  17. data/lib/mccloud/command/reload.rb +11 -0
  18. data/lib/mccloud/command/server.rb +30 -0
  19. data/lib/mccloud/command/ssh.rb +46 -0
  20. data/lib/mccloud/command/status.rb +31 -0
  21. data/lib/mccloud/command/suspend.rb +15 -0
  22. data/lib/mccloud/command/up.rb +65 -0
  23. data/lib/mccloud/config.rb +47 -0
  24. data/lib/mccloud/configurator/lb.rb +26 -0
  25. data/lib/mccloud/configurator/mccloud.rb +13 -0
  26. data/lib/mccloud/configurator/vm.rb +37 -0
  27. data/lib/mccloud/generators.rb +28 -0
  28. data/lib/mccloud/provisioner/chef_solo.rb +149 -0
  29. data/lib/mccloud/provisioner/puppet.rb +39 -0
  30. data/lib/mccloud/provisioner/vagrant/base.rb +63 -0
  31. data/lib/mccloud/provisioner/vagrant/chef.rb +130 -0
  32. data/lib/mccloud/provisioner/vagrant/chef_server.rb +103 -0
  33. data/lib/mccloud/provisioner/vagrant/chef_solo.rb +142 -0
  34. data/lib/mccloud/provisioner/vagrant/puppet.rb +137 -0
  35. data/lib/mccloud/provisioner/vagrant/puppet_server.rb +55 -0
  36. data/lib/mccloud/provisioner/vagrant/shell.rb +52 -0
  37. data/lib/mccloud/session.rb +199 -0
  38. data/lib/mccloud/templates/Mccloudfilet +44 -0
  39. data/lib/mccloud/type/forwarding.rb +11 -0
  40. data/lib/mccloud/type/lb.rb +34 -0
  41. data/lib/mccloud/type/vm.rb +46 -0
  42. data/lib/mccloud/util/iterator.rb +21 -0
  43. data/lib/mccloud/util/platform.rb +29 -0
  44. data/lib/mccloud/util/rsync.rb +21 -0
  45. data/lib/mccloud/util/ssh.rb +167 -0
  46. data/lib/mccloud/version.rb +3 -0
  47. data/mccloud.gemspec +37 -0
  48. data/ruby-bootstrap.sh +11 -0
  49. data/ruby-bootstrap2.sh +39 -0
  50. metadata +297 -0
@@ -0,0 +1,149 @@
1
+ require 'mccloud/util/rsync'
2
+ require 'mccloud/util/ssh'
3
+ module Mccloud
4
+ module Provisioner
5
+ class ChefSolo
6
+ attr_accessor :cookbooks_path
7
+ attr_accessor :role_path
8
+ attr_accessor :provisioning_path
9
+ attr_accessor :json
10
+ attr_reader :roles
11
+ attr_accessor :node_name
12
+ attr_accessor :log_level
13
+ attr_accessor :http_proxy
14
+ attr_accessor :http_proxy_user
15
+ attr_accessor :http_proxy_pass
16
+ attr_accessor :https_proxy
17
+ attr_accessor :https_proxy_user
18
+ attr_accessor :https_proxy_pass
19
+ attr_accessor :no_proxy
20
+
21
+ def initialize
22
+ @provisioning_path="/tmp/mccloud-chef"
23
+ @json={ :instance_role => "mccloud"}
24
+ end
25
+
26
+ def run(vm)
27
+ puts "we ran mylord"
28
+ json=@json.to_json
29
+ puts json
30
+ cooks=Array.new
31
+ @cookbooks_path.each do |cook|
32
+ cooks << File.join("/tmp/"+File.basename(cook))
33
+ end
34
+ cookpath="cookbook_path [\""+cooks.join("\",\"")+"\"]"
35
+ loglevel="loglevel :debug"
36
+ configfile=['file_cache_path "/var/chef-solo"',cookpath,loglevel]
37
+ vm.instance.scp(StringIO.new(json),"/tmp/dna.json")
38
+ vm.instance.scp(StringIO.new(configfile.join("\n")),"/tmp/solo.rb")
39
+
40
+ # Share the cookbooks
41
+ cookbooks_path.each do |path|
42
+ Mccloud::Util.rsync(path,vm,vm.instance)
43
+ end
44
+
45
+ puts "Running chef-solo"
46
+ options={ :port => 22, :keys => [ vm.key ], :paranoid => false, :keys_only => true}
47
+ Mccloud::Util.ssh(vm.instance.public_ip_address,vm.user,options,"sudo chef-solo -c /tmp/solo.rb -j /tmp/dna.json -l debug")
48
+
49
+ end
50
+ # Returns the run list for the provisioning
51
+ def run_list
52
+ json[:run_list] ||= []
53
+ end
54
+ # Sets the run list to the specified value
55
+ def run_list=(value)
56
+ json[:run_list] = value
57
+ end
58
+ def add_role(name)
59
+ name = "role[#{name}]" unless name =~ /^role\[(.+?)\]$/
60
+ run_list << name
61
+ end
62
+ def add_recipe(name)
63
+ name = "recipe[#{name}]" unless name =~ /^recipe\[(.+?)\]$/
64
+ run_list << name
65
+ end
66
+
67
+ def setup_config(template, filename, template_vars)
68
+ config_file = TemplateRenderer.render(template, {
69
+ :log_level => config.log_level.to_sym,
70
+ :http_proxy => config.http_proxy,
71
+ :http_proxy_user => config.http_proxy_user,
72
+ :http_proxy_pass => config.http_proxy_pass,
73
+ :https_proxy => config.https_proxy,
74
+ :https_proxy_user => config.https_proxy_user,
75
+ :https_proxy_pass => config.https_proxy_pass,
76
+ :no_proxy => config.no_proxy
77
+ }.merge(template_vars))
78
+
79
+ # file_cache_path "/var/chef-solo"
80
+ # cookbook_path "/var/chef-solo/cookbooks"
81
+
82
+ #vm.ssh.upload!(StringIO.new(config_file), File.join(config.provisioning_path, filename))
83
+ end
84
+
85
+ def setup_json
86
+
87
+ json = Mccloud::Config.config.chef.json.to_json
88
+ #vm.ssh.upload!(StringIO.new(json), File.join(config.provisioning_path, "dna.json"))
89
+ return json
90
+ end
91
+
92
+ def prepare
93
+ share_cookbook_folders
94
+ share_role_folders
95
+ end
96
+
97
+ def provision!
98
+ verify_binary("chef-solo")
99
+ chown_provisioning_folder
100
+ setup_json
101
+ setup_solo_config
102
+ run_chef_solo
103
+ end
104
+
105
+ def share_cookbook_folders
106
+ host_cookbook_paths.each_with_index do |cookbook, i|
107
+ env.config.vm.share_folder("v-csc-#{i}", cookbook_path(i), cookbook)
108
+ end
109
+ end
110
+
111
+ def share_role_folders
112
+ host_role_paths.each_with_index do |role, i|
113
+ env.config.vm.share_folder("v-csr-#{i}", role_path(i), role)
114
+ end
115
+ end
116
+
117
+ def setup_solo_config
118
+ setup_config("chef_solo_solo", "solo.rb", {
119
+ :node_name => config.node_name,
120
+ :provisioning_path => config.provisioning_path,
121
+ :cookbooks_path => cookbooks_path,
122
+ :log_level => :debug,
123
+ :recipe_url => config.recipe_url,
124
+ :roles_path => roles_path,
125
+ })
126
+ end
127
+ def run_chef_solo
128
+ commands = ["cd #{config.provisioning_path}", "chef-solo -c solo.rb -j dna.json"]
129
+
130
+ env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
131
+ vm.ssh.execute do |ssh|
132
+ ssh.sudo!(commands) do |channel, type, data|
133
+ if type == :exit_status
134
+ ssh.check_exit_status(data, commands)
135
+ else
136
+ env.ui.info("#{data}: #{type}")
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end #Module Provisioners
143
+ end #Module Mccloud
144
+
145
+
146
+ #cookbook_path "/etc/chef/recipes/cookbooks"
147
+ #log_level :info
148
+ #file_store_path "/etc/chef/recipes/"
149
+ #file_cache_path "/etc/chef/recipes/"
@@ -0,0 +1,39 @@
1
+ require 'mccloud/util/rsync'
2
+ require 'mccloud/util/ssh'
3
+ module Mccloud
4
+ module Provisioner
5
+ class Puppet
6
+
7
+ attr_accessor :manifest_file
8
+ attr_accessor :manifests_path
9
+ attr_accessor :module_path
10
+ attr_accessor :pp_path
11
+ attr_accessor :options
12
+
13
+ def initialize
14
+ @manifest_file = nil
15
+ @manifests_path = "manifests"
16
+ @module_path = nil
17
+ @pp_path = "/tmp/vagrant-puppet"
18
+ @options = []
19
+ end
20
+
21
+ def run(vm)
22
+ # @module_paths.each do |from, to|
23
+ # Mccloud::Util.rsync(path,vm,vm.instance)
24
+ # end
25
+
26
+ # @manifests_paths.each do |from, to|
27
+ # Mccloud::Util.rsync(path,vm,vm.instance)
28
+ # end
29
+ vm.instance.ssh("mkdir -p #{@pp_path}")
30
+ vm.instance.scp(@manifest_file,"#{@pp_path}/manifest.pp")
31
+
32
+ puts "Running puppet"
33
+ options={ :port => 22, :keys => [ vm.key ], :paranoid => false, :keys_only => true}
34
+ Mccloud::Util.ssh(vm.instance.public_ip_address,vm.user,options,"sudo puppet #{@pp_path}/manifest.pp")
35
+
36
+ end
37
+ end #Class
38
+ end #Module Provisioners
39
+ end #Module Mccloud
@@ -0,0 +1,63 @@
1
+ module Vagrant
2
+ module Provisioners
3
+ # The base class for a "provisioner." A provisioner is responsible for
4
+ # provisioning a Vagrant system. This has been abstracted out to provide
5
+ # support for multiple solutions such as Chef Solo, Chef Client, and
6
+ # Puppet.
7
+ class Base
8
+ include Vagrant::Util
9
+
10
+ # The environment which provisioner is running in. This is a
11
+ # {Vagrant::Action::Environment}
12
+ attr_reader :action_env
13
+
14
+ # The configuration for this provisioner. This will be an instance of
15
+ # the `Config` class which is part of the provisioner.
16
+ attr_reader :config
17
+
18
+ # Registers a provisioner with a given shortcut. This allows that provisioner
19
+ # to be referenced with the shortcut.
20
+ #
21
+ # @param [Symbol] shortcut
22
+ def self.register(shortcut)
23
+ registered[shortcut] = self
24
+ end
25
+
26
+ # Returns the provisioner associated with the given shortcut.
27
+ def self.registered
28
+ @@registered ||= {}
29
+ end
30
+
31
+ def initialize(env, config)
32
+ @action_env = env
33
+ @config = config
34
+ end
35
+
36
+ # Returns the actual {Vagrant::Environment} which this provisioner
37
+ # represents.
38
+ #
39
+ # @return [Vagrant::Environment]
40
+ def env
41
+ action_env.env
42
+ end
43
+
44
+ # Returns the VM which this provisioner is working on.
45
+ #
46
+ # @return [Vagrant::VM]
47
+ def vm
48
+ env.vm
49
+ end
50
+
51
+ # This is the method called to "prepare" the provisioner. This is called
52
+ # before any actions are run by the action runner (see {Vagrant::Actions::Runner}).
53
+ # This can be used to setup shared folders, forward ports, etc. Whatever is
54
+ # necessary on a "meta" level.
55
+ def prepare; end
56
+
57
+ # This is the method called to provision the system. This method
58
+ # is expected to do whatever necessary to provision the system (create files,
59
+ # SSH, etc.)
60
+ def provision!; end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,130 @@
1
+ module Vagrant
2
+ module Provisioners
3
+ # This class is a base class where the common functionality shared between
4
+ # chef-solo and chef-client provisioning are stored. This is **not an actual
5
+ # provisioner**. Instead, {ChefSolo} or {ChefServer} should be used.
6
+ class Chef < Base
7
+ def prepare
8
+ raise ChefError, :invalid_provisioner
9
+ end
10
+
11
+ def verify_binary(binary)
12
+ vm.ssh.execute do |ssh|
13
+ # Checks for the existence of chef binary and error if it
14
+ # doesn't exist.
15
+ ssh.sudo!("which #{binary}", :error_class => ChefError, :_key => :chef_not_detected, :binary => binary)
16
+ end
17
+ end
18
+
19
+ def chown_provisioning_folder
20
+ vm.ssh.execute do |ssh|
21
+ ssh.sudo!("mkdir -p #{config.provisioning_path}")
22
+ ssh.sudo!("chown #{env.config.ssh.username} #{config.provisioning_path}")
23
+ end
24
+ end
25
+
26
+ def setup_config(template, filename, template_vars)
27
+ config_file = TemplateRenderer.render(template, {
28
+ :log_level => config.log_level.to_sym,
29
+ :http_proxy => config.http_proxy,
30
+ :http_proxy_user => config.http_proxy_user,
31
+ :http_proxy_pass => config.http_proxy_pass,
32
+ :https_proxy => config.https_proxy,
33
+ :https_proxy_user => config.https_proxy_user,
34
+ :https_proxy_pass => config.https_proxy_pass,
35
+ :no_proxy => config.no_proxy
36
+ }.merge(template_vars))
37
+
38
+ vm.ssh.upload!(StringIO.new(config_file), File.join(config.provisioning_path, filename))
39
+ end
40
+
41
+ def setup_json
42
+ env.ui.info I18n.t("vagrant.provisioners.chef.json")
43
+
44
+ # Set up initial configuration
45
+ data = {
46
+ :config => env.config.to_hash,
47
+ :directory => env.config.vm.shared_folders["v-root"][:guestpath],
48
+ }
49
+
50
+ # And wrap it under the "vagrant" namespace
51
+ data = { :vagrant => data }
52
+
53
+ # Merge with the "extra data" which isn't put under the
54
+ # vagrant namespace by default
55
+ data.merge!(config.json)
56
+
57
+ json = data.to_json
58
+
59
+ vm.ssh.upload!(StringIO.new(json), File.join(config.provisioning_path, "dna.json"))
60
+ end
61
+ end
62
+
63
+ class Chef < Base
64
+ class ChefError < Errors::VagrantError
65
+ error_namespace("vagrant.provisioners.chef")
66
+ end
67
+ end
68
+
69
+ class Chef < Base
70
+ # This is the configuration which is available through `config.chef`
71
+ class Config < Vagrant::Config::Base
72
+ # Shared config
73
+ attr_accessor :node_name
74
+ attr_accessor :provisioning_path
75
+ attr_accessor :log_level
76
+ attr_accessor :json
77
+ attr_accessor :http_proxy
78
+ attr_accessor :http_proxy_user
79
+ attr_accessor :http_proxy_pass
80
+ attr_accessor :https_proxy
81
+ attr_accessor :https_proxy_user
82
+ attr_accessor :https_proxy_pass
83
+ attr_accessor :no_proxy
84
+
85
+ def initialize
86
+ @provisioning_path = "/tmp/vagrant-chef"
87
+ @log_level = :info
88
+ @json = { :instance_role => "vagrant" }
89
+ @http_proxy = nil
90
+ @http_proxy_user = nil
91
+ @http_proxy_pass = nil
92
+ @https_proxy = nil
93
+ @https_proxy_user = nil
94
+ @https_proxy_pass = nil
95
+ @no_proxy = nil
96
+ end
97
+
98
+ # Returns the run list for the provisioning
99
+ def run_list
100
+ json[:run_list] ||= []
101
+ end
102
+
103
+ # Sets the run list to the specified value
104
+ def run_list=(value)
105
+ json[:run_list] = value
106
+ end
107
+
108
+ # Adds a recipe to the run list
109
+ def add_recipe(name)
110
+ name = "recipe[#{name}]" unless name =~ /^recipe\[(.+?)\]$/
111
+ run_list << name
112
+ end
113
+
114
+ # Adds a role to the run list
115
+ def add_role(name)
116
+ name = "role[#{name}]" unless name =~ /^role\[(.+?)\]$/
117
+ run_list << name
118
+ end
119
+
120
+ def instance_variables_hash
121
+ # Overridden so that the 'json' key could be removed, since its just
122
+ # merged into the config anyways
123
+ result = super
124
+ result.delete("json")
125
+ result
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,103 @@
1
+ require 'pathname'
2
+
3
+ module Vagrant
4
+ module Provisioners
5
+ # This class implements provisioning via chef-client, allowing provisioning
6
+ # with a chef server.
7
+ class ChefServer < Chef
8
+ register :chef_server
9
+
10
+ class Config < Chef::Config
11
+ attr_accessor :chef_server_url
12
+ attr_accessor :validation_key_path
13
+ attr_accessor :validation_client_name
14
+ attr_accessor :client_key_path
15
+ attr_accessor :file_cache_path
16
+ attr_accessor :file_backup_path
17
+
18
+ def initialize
19
+ super
20
+
21
+ @validation_client_name = "chef-validator"
22
+ @client_key_path = "/etc/chef/client.pem"
23
+ @file_cache_path = "/srv/chef/file_store"
24
+ @file_backup_path = "/srv/chef/cache"
25
+ end
26
+
27
+ def validate(errors)
28
+ super
29
+
30
+ errors.add(I18n.t("vagrant.config.chef.server_url_empty")) if !chef_server_url || chef_server_url.strip == ""
31
+ errors.add(I18n.t("vagrant.config.chef.validation_key_path")) if !validation_key_path
32
+ errors.add(I18n.t("vagrant.config.chef.run_list_empty")) if json[:run_list] && run_list.empty?
33
+ end
34
+ end
35
+
36
+ def prepare
37
+ raise ChefError, :server_validation_key_required if config.validation_key_path.nil?
38
+ raise ChefError, :server_validation_key_doesnt_exist if !File.file?(validation_key_path)
39
+ raise ChefError, :server_url_required if config.chef_server_url.nil?
40
+ end
41
+
42
+ def provision!
43
+ verify_binary("chef-client")
44
+ chown_provisioning_folder
45
+ create_client_key_folder
46
+ upload_validation_key
47
+ setup_json
48
+ setup_server_config
49
+ run_chef_client
50
+ end
51
+
52
+ def create_client_key_folder
53
+ env.ui.info I18n.t("vagrant.provisioners.chef.client_key_folder")
54
+ path = Pathname.new(config.client_key_path)
55
+
56
+ vm.ssh.execute do |ssh|
57
+ ssh.sudo!("mkdir -p #{path.dirname}")
58
+ end
59
+ end
60
+
61
+ def upload_validation_key
62
+ env.ui.info I18n.t("vagrant.provisioners.chef.upload_validation_key")
63
+ vm.ssh.upload!(validation_key_path, guest_validation_key_path)
64
+ end
65
+
66
+ def setup_server_config
67
+ setup_config("chef_server_client", "client.rb", {
68
+ :node_name => config.node_name,
69
+ :chef_server_url => config.chef_server_url,
70
+ :validation_client_name => config.validation_client_name,
71
+ :validation_key => guest_validation_key_path,
72
+ :client_key => config.client_key_path,
73
+ :file_cache_path => config.file_cache_path,
74
+ :file_backup_path => config.file_backup_path
75
+ })
76
+ end
77
+
78
+ def run_chef_client
79
+ commands = ["cd #{config.provisioning_path}",
80
+ "chef-client -c client.rb -j dna.json"]
81
+
82
+ env.ui.info I18n.t("vagrant.provisioners.chef.running_client")
83
+ vm.ssh.execute do |ssh|
84
+ ssh.sudo!(commands) do |channel, type, data|
85
+ if type == :exit_status
86
+ ssh.check_exit_status(data, commands)
87
+ else
88
+ env.ui.info("#{data}: #{type}")
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def validation_key_path
95
+ File.expand_path(config.validation_key_path, env.root_path)
96
+ end
97
+
98
+ def guest_validation_key_path
99
+ File.join(config.provisioning_path, "validation.pem")
100
+ end
101
+ end
102
+ end
103
+ end