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.
- data/.gitignore +5 -0
- data/.rvmrc +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +74 -0
- data/README.md +123 -0
- data/Rakefile +5 -0
- data/bin/mccloud +116 -0
- data/lib/mccloud.rb +2 -0
- data/lib/mccloud/command/boot.rb +12 -0
- data/lib/mccloud/command/bootstrap.rb +31 -0
- data/lib/mccloud/command/command.rb +21 -0
- data/lib/mccloud/command/destroy.rb +19 -0
- data/lib/mccloud/command/halt.rb +19 -0
- data/lib/mccloud/command/init.rb +7 -0
- data/lib/mccloud/command/multi.rb +53 -0
- data/lib/mccloud/command/provision.rb +28 -0
- data/lib/mccloud/command/reload.rb +11 -0
- data/lib/mccloud/command/server.rb +30 -0
- data/lib/mccloud/command/ssh.rb +46 -0
- data/lib/mccloud/command/status.rb +31 -0
- data/lib/mccloud/command/suspend.rb +15 -0
- data/lib/mccloud/command/up.rb +65 -0
- data/lib/mccloud/config.rb +47 -0
- data/lib/mccloud/configurator/lb.rb +26 -0
- data/lib/mccloud/configurator/mccloud.rb +13 -0
- data/lib/mccloud/configurator/vm.rb +37 -0
- data/lib/mccloud/generators.rb +28 -0
- data/lib/mccloud/provisioner/chef_solo.rb +149 -0
- data/lib/mccloud/provisioner/puppet.rb +39 -0
- data/lib/mccloud/provisioner/vagrant/base.rb +63 -0
- data/lib/mccloud/provisioner/vagrant/chef.rb +130 -0
- data/lib/mccloud/provisioner/vagrant/chef_server.rb +103 -0
- data/lib/mccloud/provisioner/vagrant/chef_solo.rb +142 -0
- data/lib/mccloud/provisioner/vagrant/puppet.rb +137 -0
- data/lib/mccloud/provisioner/vagrant/puppet_server.rb +55 -0
- data/lib/mccloud/provisioner/vagrant/shell.rb +52 -0
- data/lib/mccloud/session.rb +199 -0
- data/lib/mccloud/templates/Mccloudfilet +44 -0
- data/lib/mccloud/type/forwarding.rb +11 -0
- data/lib/mccloud/type/lb.rb +34 -0
- data/lib/mccloud/type/vm.rb +46 -0
- data/lib/mccloud/util/iterator.rb +21 -0
- data/lib/mccloud/util/platform.rb +29 -0
- data/lib/mccloud/util/rsync.rb +21 -0
- data/lib/mccloud/util/ssh.rb +167 -0
- data/lib/mccloud/version.rb +3 -0
- data/mccloud.gemspec +37 -0
- data/ruby-bootstrap.sh +11 -0
- data/ruby-bootstrap2.sh +39 -0
- metadata +297 -0
| @@ -0,0 +1,142 @@ | |
| 1 | 
            +
            module Vagrant
         | 
| 2 | 
            +
              module Provisioners
         | 
| 3 | 
            +
                # This class implements provisioning via chef-solo.
         | 
| 4 | 
            +
                class ChefSolo < Chef
         | 
| 5 | 
            +
                  register :chef_solo
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  class Config < Chef::Config
         | 
| 8 | 
            +
                    attr_accessor :cookbooks_path
         | 
| 9 | 
            +
                    attr_accessor :roles_path
         | 
| 10 | 
            +
                    attr_accessor :recipe_url
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    def initialize
         | 
| 13 | 
            +
                      super
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                      @cookbooks_path = ["cookbooks", [:vm, "cookbooks"]]
         | 
| 16 | 
            +
                      @roles_path = []
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    def validate(errors)
         | 
| 20 | 
            +
                      super
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                      errors.add(I18n.t("vagrant.config.chef.cookbooks_path_empty")) if !cookbooks_path || [cookbooks_path].flatten.empty?
         | 
| 23 | 
            +
                      errors.add(I18n.t("vagrant.config.chef.run_list_empty")) if !json[:run_list] || run_list.empty?
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  def prepare
         | 
| 28 | 
            +
                    share_cookbook_folders
         | 
| 29 | 
            +
                    share_role_folders
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def provision!
         | 
| 33 | 
            +
                    verify_binary("chef-solo")
         | 
| 34 | 
            +
                    chown_provisioning_folder
         | 
| 35 | 
            +
                    setup_json
         | 
| 36 | 
            +
                    setup_solo_config
         | 
| 37 | 
            +
                    run_chef_solo
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def share_cookbook_folders
         | 
| 41 | 
            +
                    host_cookbook_paths.each_with_index do |cookbook, i|
         | 
| 42 | 
            +
                      env.config.vm.share_folder("v-csc-#{i}", cookbook_path(i), cookbook)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def share_role_folders
         | 
| 47 | 
            +
                    host_role_paths.each_with_index do |role, i|
         | 
| 48 | 
            +
                      env.config.vm.share_folder("v-csr-#{i}", role_path(i), role)
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def setup_solo_config
         | 
| 53 | 
            +
                    setup_config("chef_solo_solo", "solo.rb", {
         | 
| 54 | 
            +
                      :node_name => config.node_name,
         | 
| 55 | 
            +
                      :provisioning_path => config.provisioning_path,
         | 
| 56 | 
            +
                      :cookbooks_path => cookbooks_path,
         | 
| 57 | 
            +
                      :recipe_url => config.recipe_url,
         | 
| 58 | 
            +
                      :roles_path => roles_path,
         | 
| 59 | 
            +
                    })
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  def run_chef_solo
         | 
| 63 | 
            +
                    commands = ["cd #{config.provisioning_path}", "chef-solo -c solo.rb -j dna.json"]
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
         | 
| 66 | 
            +
                    vm.ssh.execute do |ssh|
         | 
| 67 | 
            +
                      ssh.sudo!(commands) do |channel, type, data|
         | 
| 68 | 
            +
                        if type == :exit_status
         | 
| 69 | 
            +
                          ssh.check_exit_status(data, commands)
         | 
| 70 | 
            +
                        else
         | 
| 71 | 
            +
                          env.ui.info("#{data}: #{type}")
         | 
| 72 | 
            +
                        end
         | 
| 73 | 
            +
                      end
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def host_folder_paths(paths)
         | 
| 78 | 
            +
                    # Convert single cookbook paths such as "cookbooks" or [:vm, "cookbooks"]
         | 
| 79 | 
            +
                    # into a proper array representation.
         | 
| 80 | 
            +
                    paths = [paths] if paths.is_a?(String) || paths.first.is_a?(Symbol)
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    paths.inject([]) do |acc, path|
         | 
| 83 | 
            +
                      path = [:host, path] if !path.is_a?(Array)
         | 
| 84 | 
            +
                      type, path = path
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                      acc << File.expand_path(path, env.root_path) if type == :host
         | 
| 87 | 
            +
                      acc
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  def folder_path(*args)
         | 
| 92 | 
            +
                    File.join(config.provisioning_path, args.join("-"))
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  def folders_path(folders, folder)
         | 
| 96 | 
            +
                    # Convert single cookbook paths such as "cookbooks" or [:vm, "cookbooks"]
         | 
| 97 | 
            +
                    # into a proper array representation.
         | 
| 98 | 
            +
                    folders = [folders] if folders.is_a?(String) || folders.first.is_a?(Symbol)
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                    # Convert each path to the proper absolute path depending on if the path
         | 
| 101 | 
            +
                    # is a host path or a VM path
         | 
| 102 | 
            +
                    result = []
         | 
| 103 | 
            +
                    folders.each_with_index do |path, i|
         | 
| 104 | 
            +
                      path = [:host, path] if !path.is_a?(Array)
         | 
| 105 | 
            +
                      type, path = path
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                      result << folder_path(folder, i) if type == :host
         | 
| 108 | 
            +
                      result << folder_path(path) if type == :vm
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                    # We're lucky that ruby's string and array syntax for strings is the
         | 
| 112 | 
            +
                    # same as JSON, so we can just convert to JSON here and use that
         | 
| 113 | 
            +
                    result = result[0].to_s if result.length == 1
         | 
| 114 | 
            +
                    result
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  def host_cookbook_paths
         | 
| 118 | 
            +
                    host_folder_paths(config.cookbooks_path)
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                  def host_role_paths
         | 
| 122 | 
            +
                    host_folder_paths(config.roles_path)
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  def cookbook_path(i)
         | 
| 126 | 
            +
                    folder_path("cookbooks", i)
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                  def role_path(i)
         | 
| 130 | 
            +
                    folder_path("roles", i)
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                  def cookbooks_path
         | 
| 134 | 
            +
                    folders_path(config.cookbooks_path, "cookbooks").to_json
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  def roles_path
         | 
| 138 | 
            +
                    folders_path(config.roles_path, "roles").to_json
         | 
| 139 | 
            +
                  end
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
            end
         | 
| @@ -0,0 +1,137 @@ | |
| 1 | 
            +
            module Vagrant
         | 
| 2 | 
            +
              module Provisioners
         | 
| 3 | 
            +
                class PuppetError < Vagrant::Errors::VagrantError
         | 
| 4 | 
            +
                  error_namespace("vagrant.provisioners.puppet")
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                class Puppet < Base
         | 
| 8 | 
            +
                  register :puppet
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  class Config < Vagrant::Config::Base
         | 
| 11 | 
            +
                    attr_accessor :manifest_file
         | 
| 12 | 
            +
                    attr_accessor :manifests_path
         | 
| 13 | 
            +
                    attr_accessor :module_path
         | 
| 14 | 
            +
                    attr_accessor :pp_path
         | 
| 15 | 
            +
                    attr_accessor :options
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    def initialize
         | 
| 18 | 
            +
                      @manifest_file = nil
         | 
| 19 | 
            +
                      @manifests_path = "manifests"
         | 
| 20 | 
            +
                      @module_path = nil
         | 
| 21 | 
            +
                      @pp_path = "/tmp/vagrant-puppet"
         | 
| 22 | 
            +
                      @options = []
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    # Returns the manifests path expanded relative to the root path of the
         | 
| 26 | 
            +
                    # environment.
         | 
| 27 | 
            +
                    def expanded_manifests_path
         | 
| 28 | 
            +
                      Pathname.new(manifests_path).expand_path(env.root_path)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    # Returns the manifest file if set otherwise returns the box name pp file
         | 
| 32 | 
            +
                    # which may or may not exist.
         | 
| 33 | 
            +
                    def computed_manifest_file
         | 
| 34 | 
            +
                      manifest_file || "#{top.vm.box}.pp"
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    # Returns the module paths as an array of paths expanded relative to the
         | 
| 38 | 
            +
                    # root path.
         | 
| 39 | 
            +
                    def expanded_module_paths
         | 
| 40 | 
            +
                      return [] if !module_path
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      # Get all the paths and expand them relative to the root path, returning
         | 
| 43 | 
            +
                      # the array of expanded paths
         | 
| 44 | 
            +
                      paths = module_path
         | 
| 45 | 
            +
                      paths = [paths] if !paths.is_a?(Array)
         | 
| 46 | 
            +
                      paths.map do |path|
         | 
| 47 | 
            +
                        Pathname.new(path).expand_path(env.root_path)
         | 
| 48 | 
            +
                      end
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    def validate(errors)
         | 
| 52 | 
            +
                      super
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                      # Manifests path/file validation
         | 
| 55 | 
            +
                      if !expanded_manifests_path.directory?
         | 
| 56 | 
            +
                        errors.add(I18n.t("vagrant.provisioners.puppet.manifests_path_missing", :path => expanded_manifests_path))
         | 
| 57 | 
            +
                      else
         | 
| 58 | 
            +
                        if !expanded_manifests_path.join(computed_manifest_file).file?
         | 
| 59 | 
            +
                          errors.add(I18n.t("vagrant.provisioners.puppet.manifest_missing", :manifest => computed_manifest_file))
         | 
| 60 | 
            +
                        end
         | 
| 61 | 
            +
                      end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                      # Module paths validation
         | 
| 64 | 
            +
                      expanded_module_paths.each do |path|
         | 
| 65 | 
            +
                        if !path.directory?
         | 
| 66 | 
            +
                          errors.add(I18n.t("vagrant.provisioners.puppet.module_path_missing", :path => path))
         | 
| 67 | 
            +
                        end
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  def prepare
         | 
| 73 | 
            +
                    set_module_paths
         | 
| 74 | 
            +
                    share_manifests
         | 
| 75 | 
            +
                    share_module_paths
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  def provision!
         | 
| 79 | 
            +
                    verify_binary("puppet")
         | 
| 80 | 
            +
                    run_puppet_client
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def share_manifests
         | 
| 84 | 
            +
                    env.config.vm.share_folder("manifests", manifests_guest_path, config.expanded_manifests_path)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  def share_module_paths
         | 
| 88 | 
            +
                    count = 0
         | 
| 89 | 
            +
                    @module_paths.each do |from, to|
         | 
| 90 | 
            +
                      # Sorry for the cryptic key here, but VirtualBox has a strange limit on
         | 
| 91 | 
            +
                      # maximum size for it and its something small (around 10)
         | 
| 92 | 
            +
                      env.config.vm.share_folder("v-pp-m#{count}", to, from)
         | 
| 93 | 
            +
                      count += 1
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  def set_module_paths
         | 
| 98 | 
            +
                    @module_paths = {}
         | 
| 99 | 
            +
                    config.expanded_module_paths.each_with_index do |path, i|
         | 
| 100 | 
            +
                      @module_paths[path] = File.join(config.pp_path, "modules-#{i}")
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  def manifests_guest_path
         | 
| 105 | 
            +
                    File.join(config.pp_path, "manifests")
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  def verify_binary(binary)
         | 
| 109 | 
            +
                    vm.ssh.execute do |ssh|
         | 
| 110 | 
            +
                      ssh.sudo!("which #{binary}", :error_class => PuppetError, :_key => :puppet_not_detected, :binary => binary)
         | 
| 111 | 
            +
                    end
         | 
| 112 | 
            +
                  end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                  def run_puppet_client
         | 
| 115 | 
            +
                    options = [config.options].flatten
         | 
| 116 | 
            +
                    options << "--modulepath '#{@module_paths.values.join(':')}'" if !@module_paths.empty?
         | 
| 117 | 
            +
                    options << config.computed_manifest_file
         | 
| 118 | 
            +
                    options = options.join(" ")
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                    commands = ["cd #{manifests_guest_path}",
         | 
| 121 | 
            +
                                "puppet #{options}"]
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                    env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet", :manifest => config.computed_manifest_file)
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                    vm.ssh.execute do |ssh|
         | 
| 126 | 
            +
                      ssh.sudo! commands do |ch, type, data|
         | 
| 127 | 
            +
                        if type == :exit_status
         | 
| 128 | 
            +
                          ssh.check_exit_status(data, commands)
         | 
| 129 | 
            +
                        else
         | 
| 130 | 
            +
                          env.ui.info(data)
         | 
| 131 | 
            +
                        end
         | 
| 132 | 
            +
                      end
         | 
| 133 | 
            +
                    end
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
                end
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            module Vagrant
         | 
| 2 | 
            +
              module Provisioners
         | 
| 3 | 
            +
                class PuppetServerError < Vagrant::Errors::VagrantError
         | 
| 4 | 
            +
                  error_namespace("vagrant.provisioners.puppet_server")
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                class PuppetServer < Base
         | 
| 8 | 
            +
                  register :puppet_server
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  class Config < Vagrant::Config::Base
         | 
| 11 | 
            +
                    attr_accessor :puppet_server
         | 
| 12 | 
            +
                    attr_accessor :puppet_node
         | 
| 13 | 
            +
                    attr_accessor :options
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def initialize
         | 
| 16 | 
            +
                      @puppet_server = "puppet"
         | 
| 17 | 
            +
                      @puppet_node = "puppet_node"
         | 
| 18 | 
            +
                      @options = []
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def provision!
         | 
| 23 | 
            +
                    verify_binary("puppetd")
         | 
| 24 | 
            +
                    run_puppetd_client
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  def verify_binary(binary)
         | 
| 28 | 
            +
                    vm.ssh.execute do |ssh|
         | 
| 29 | 
            +
                      ssh.sudo!("which #{binary}", :error_class => PuppetServerError, :_key => :puppetd_not_detected, :binary => binary)
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def run_puppetd_client
         | 
| 34 | 
            +
                    options = config.options
         | 
| 35 | 
            +
                    options = options.join(" ") if options.is_a?(Array)
         | 
| 36 | 
            +
                    if config.puppet_node
         | 
| 37 | 
            +
                      cn = config.puppet_node
         | 
| 38 | 
            +
                    else
         | 
| 39 | 
            +
                      cn = env.config.vm.box
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    commands = "puppetd #{options} --server #{config.puppet_server} --certname #{cn}"
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    env.ui.info I18n.t("vagrant.provisioners.puppet_server.running_puppetd")
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    vm.ssh.execute do |ssh|
         | 
| 47 | 
            +
                      ssh.sudo!(commands) do |channel, type, data|
         | 
| 48 | 
            +
                        ssh.check_exit_status(data, commands) if type == :exit_status
         | 
| 49 | 
            +
                        env.ui.info(data) if type != :exit_status
         | 
| 50 | 
            +
                      end
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            module Vagrant
         | 
| 2 | 
            +
              module Provisioners
         | 
| 3 | 
            +
                class Shell < Base
         | 
| 4 | 
            +
                  register :shell
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  class Config < Vagrant::Config::Base
         | 
| 7 | 
            +
                    attr_accessor :path
         | 
| 8 | 
            +
                    attr_accessor :upload_path
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def initialize
         | 
| 11 | 
            +
                      @upload_path = "/tmp/vagrant-shell"
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def expanded_path
         | 
| 15 | 
            +
                      Pathname.new(path).expand_path(env.root_path) if path
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    def validate(errors)
         | 
| 19 | 
            +
                      super
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      if !path
         | 
| 22 | 
            +
                        errors.add(I18n.t("vagrant.provisioners.shell.path_not_set"))
         | 
| 23 | 
            +
                      elsif !expanded_path.file?
         | 
| 24 | 
            +
                        errors.add(I18n.t("vagrant.provisioners.shell.path_invalid", :path => expanded_path))
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                      if !upload_path
         | 
| 28 | 
            +
                        errors.add(I18n.t("vagrant.provisioners.shell.upload_path_not_set"))
         | 
| 29 | 
            +
                      end
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def provision!
         | 
| 34 | 
            +
                    commands = ["chmod +x #{config.upload_path}", config.upload_path]
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    # Upload the script to the VM
         | 
| 37 | 
            +
                    vm.ssh.upload!(config.expanded_path.to_s, config.upload_path)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    # Execute it with sudo
         | 
| 40 | 
            +
                    vm.ssh.execute do |ssh|
         | 
| 41 | 
            +
                      ssh.sudo!(commands) do |ch, type, data|
         | 
| 42 | 
            +
                        if type == :exit_status
         | 
| 43 | 
            +
                          ssh.check_exit_status(data, commands)
         | 
| 44 | 
            +
                        else
         | 
| 45 | 
            +
                          env.ui.info(data)
         | 
| 46 | 
            +
                        end
         | 
| 47 | 
            +
                      end
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,199 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
            require 'logger'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'fog'
         | 
| 6 | 
            +
            require 'highline'
         | 
| 7 | 
            +
            require 'highline/import'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            require 'mccloud/config'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            require 'mccloud/command/status'
         | 
| 12 | 
            +
            require 'mccloud/command/up'
         | 
| 13 | 
            +
            require 'mccloud/command/halt'
         | 
| 14 | 
            +
            require 'mccloud/command/ssh'
         | 
| 15 | 
            +
            require 'mccloud/command/boot'
         | 
| 16 | 
            +
            require 'mccloud/command/bootstrap'
         | 
| 17 | 
            +
            require 'mccloud/command/reload'
         | 
| 18 | 
            +
            require 'mccloud/command/multi'
         | 
| 19 | 
            +
            require 'mccloud/command/init'
         | 
| 20 | 
            +
            require 'mccloud/command/suspend'
         | 
| 21 | 
            +
            require 'mccloud/command/destroy'
         | 
| 22 | 
            +
            require 'mccloud/command/provision'
         | 
| 23 | 
            +
            require 'mccloud/command/server'
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            module Mccloud
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              # We need some global thing for the config file to find our session
         | 
| 28 | 
            +
              def self.session=(value)
         | 
| 29 | 
            +
                @session=value
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
              def self.session
         | 
| 32 | 
            +
                return @session
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              class Session
         | 
| 36 | 
            +
                attr_accessor :config
         | 
| 37 | 
            +
                attr_accessor :logger
         | 
| 38 | 
            +
                attr_accessor :all_servers
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                include Mccloud::Command
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def initialize(options=nil)
         | 
| 43 | 
            +
                  @logger = Logger.new(STDOUT)
         | 
| 44 | 
            +
                  @logger.level = Logger::DEBUG
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  #http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/classes/Logger.html
         | 
| 47 | 
            +
                  @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  #logger.formatter = proc { |severity, datetime, progname, msg|
         | 
| 50 | 
            +
                  #   "#{datetime} - #{severity}: #{msg}\n"
         | 
| 51 | 
            +
                  # }
         | 
| 52 | 
            +
                  @session=self
         | 
| 53 | 
            +
                  Mccloud.session=self
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def load_config(options=nil)
         | 
| 57 | 
            +
                  @logger.debug "Loading mccloud config"
         | 
| 58 | 
            +
                  #if File.exist?(path)
         | 
| 59 | 
            +
                  begin
         | 
| 60 | 
            +
                    Kernel.load File.join(Dir.pwd,"Mccloudfile")
         | 
| 61 | 
            +
                  rescue LoadError => e
         | 
| 62 | 
            +
                    @logger.error "Error loading configfile - Sorry"
         | 
| 63 | 
            +
                    @logger.error e.message  
         | 
| 64 | 
            +
                    @logger.error e.backtrace.inspect  
         | 
| 65 | 
            +
                    exit -1
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  @all_servers=Hash.new
         | 
| 69 | 
            +
                  if File.exists?(".mccloud")
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    @logger.debug ".mccloud exists"
         | 
| 72 | 
            +
                    dotmccloud=File.new(".mccloud")
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                    @logger.debug "reading .mccloud json file"
         | 
| 75 | 
            +
                    json=dotmccloud.readlines.to_s
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    begin
         | 
| 78 | 
            +
                      @logger.debug "parsing .mccloud json file"
         | 
| 79 | 
            +
                      @all_servers=JSON.parse(json)
         | 
| 80 | 
            +
                    rescue Error => e
         | 
| 81 | 
            +
                      @logger.error "Error parsing json file - Sorry"
         | 
| 82 | 
            +
                      @logger.error e.message  
         | 
| 83 | 
            +
                      @logger.error e.backtrace.inspect  
         | 
| 84 | 
            +
                      exit -1
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  #Loading providers
         | 
| 90 | 
            +
                  Mccloud.session.config.vms.each do |name,vm|
         | 
| 91 | 
            +
                    if @session.config.providers[vm.provider].nil?
         | 
| 92 | 
            +
                    
         | 
| 93 | 
            +
                    @logger.debug "adding provider #{vm.provider}"
         | 
| 94 | 
            +
                    begin
         | 
| 95 | 
            +
                      @session.config.providers[vm.provider]=Fog::Compute.new(:provider => vm.provider)
         | 
| 96 | 
            +
                    rescue ArgumentError => e
         | 
| 97 | 
            +
                      #  Missing required arguments: 
         | 
| 98 | 
            +
                      required_string=e.message
         | 
| 99 | 
            +
                      required_string["Missing required arguments: "]=""
         | 
| 100 | 
            +
                      required_options=required_string.split(", ")
         | 
| 101 | 
            +
                      puts "Please provide credentials for provider [#{vm.provider}]:"
         | 
| 102 | 
            +
                      answer=Hash.new
         | 
| 103 | 
            +
                      for fog_option in required_options do 
         | 
| 104 | 
            +
                        answer["#{fog_option}".to_sym]=ask("- #{fog_option}: ") 
         | 
| 105 | 
            +
                        #{ |q| q.validate = /\A\d{5}(?:-?\d{4})?\Z/ }
         | 
| 106 | 
            +
                      end
         | 
| 107 | 
            +
                      puts "\nThe following snippet will be written to #{File.join(ENV['HOME'],".fog")}"
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                      snippet=":default:\n"
         | 
| 110 | 
            +
                      for fog_option in required_options do
         | 
| 111 | 
            +
                        snippet=snippet+"  :#{fog_option}: #{answer[fog_option.to_sym]}\n"
         | 
| 112 | 
            +
                      end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                      puts "======== snippit start ====="
         | 
| 115 | 
            +
                      puts "#{snippet}"
         | 
| 116 | 
            +
                      puts "======== snippit end ======="
         | 
| 117 | 
            +
                      confirmed=agree("Do you wan to save this?: ")
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                      if (confirmed)
         | 
| 120 | 
            +
                        fogfile=File.new("#{File.join(ENV['HOME'],".fog")}","w")
         | 
| 121 | 
            +
                        fogfile.puts "#{snippet}"
         | 
| 122 | 
            +
                        fogfile.close
         | 
| 123 | 
            +
                      else
         | 
| 124 | 
            +
                        puts "Ok, we won't write it, but we continue with your credentials in memory"
         | 
| 125 | 
            +
                        exit -1
         | 
| 126 | 
            +
                      end
         | 
| 127 | 
            +
                      begin
         | 
| 128 | 
            +
                        answer[:provider]= vm.provider
         | 
| 129 | 
            +
                        @session.config.providers[vm.provider]=Fog::Compute.new(answer)
         | 
| 130 | 
            +
                      rescue
         | 
| 131 | 
            +
                          puts "We tried to create the provider but failed again, sorry we give up"
         | 
| 132 | 
            +
                          exit -1
         | 
| 133 | 
            +
                      end
         | 
| 134 | 
            +
                    end
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
                  end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                  invalid_cache=false
         | 
| 139 | 
            +
                  @session.config.vms.each do |name,vm|
         | 
| 140 | 
            +
                    prefix=@session.config.mccloud.prefix
         | 
| 141 | 
            +
                    id=@all_servers["#{name.to_s}"]
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                    #Check if not destroyed or something else
         | 
| 144 | 
            +
                    instance=vm.instance
         | 
| 145 | 
            +
                    if instance.nil?
         | 
| 146 | 
            +
                      @logger.error "Cache is invalid"
         | 
| 147 | 
            +
                      invalid_cache=true
         | 
| 148 | 
            +
                    else  
         | 
| 149 | 
            +
                      if instance.state == "shutting-down" || instance.state == "terminated"
         | 
| 150 | 
            +
                        @logger.info "parsing .mccloud json" 
         | 
| 151 | 
            +
                        @logger.info "rebuilding cache"
         | 
| 152 | 
            +
                        invalid_cache=true
         | 
| 153 | 
            +
                      end
         | 
| 154 | 
            +
                    end
         | 
| 155 | 
            +
                  end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                  #
         | 
| 158 | 
            +
                  if (invalid_cache)
         | 
| 159 | 
            +
                    #Resetting the list
         | 
| 160 | 
            +
                    @all_servers=Hash.new
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                    servers_by_provider=Hash.new
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                    # Find all providers
         | 
| 165 | 
            +
                    @session.config.providers.each do |name,provider|
         | 
| 166 | 
            +
                      server_list=Hash.new
         | 
| 167 | 
            +
                      provider.servers.each do |server|
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                        if !(server.state == "terminated")
         | 
| 170 | 
            +
                          server_list[server.tags["Name"]]=server.id	
         | 
| 171 | 
            +
                        end
         | 
| 172 | 
            +
                      end
         | 
| 173 | 
            +
                      servers_by_provider[name]=server_list
         | 
| 174 | 
            +
                    end
         | 
| 175 | 
            +
                    prefix=@session.config.mccloud.prefix
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                    @session.config.vms.each do |name,vm|
         | 
| 178 | 
            +
                      id=servers_by_provider[vm.provider]["#{prefix} - #{name.to_s}"]
         | 
| 179 | 
            +
             | 
| 180 | 
            +
             | 
| 181 | 
            +
                      if !id.nil?
         | 
| 182 | 
            +
                        @all_servers[name]=id
         | 
| 183 | 
            +
                        #@session.config.vms[name].instance=@session.config.providers[vm.provider].servers.get(id)
         | 
| 184 | 
            +
                      end
         | 
| 185 | 
            +
                    end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                    dotmccloud=File.new(".mccloud","w")
         | 
| 188 | 
            +
                    dotmccloud.puts(@all_servers.to_json)
         | 
| 189 | 
            +
                    dotmccloud.close
         | 
| 190 | 
            +
             | 
| 191 | 
            +
             | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
                end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
             | 
| 196 | 
            +
             | 
| 197 | 
            +
             | 
| 198 | 
            +
              end
         | 
| 199 | 
            +
            end
         |