mccloud 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,53 @@
|
|
1
|
+
require 'net/ssh/multi'
|
2
|
+
|
3
|
+
module Mccloud
|
4
|
+
module Command
|
5
|
+
#http://stackoverflow.com/questions/1383282/netsshmulti-using-the-session-exec-how-do-you-get-the-output-straight-away
|
6
|
+
#https://gist.github.com/700730
|
7
|
+
def multi(selection=nil,command="who am i",options=nil)
|
8
|
+
trap("INT") { puts "we hit CTRL_C"; exit }
|
9
|
+
|
10
|
+
Net::SSH::Multi.start do |session|
|
11
|
+
# Connect to remote machines
|
12
|
+
ip2name=Hash.new
|
13
|
+
on_selected_machines(selection) do |id,vm|
|
14
|
+
instance=vm.instance
|
15
|
+
if instance.state == "running"
|
16
|
+
ip2name[instance.public_ip_address]=vm.name
|
17
|
+
session.use "#{instance.public_ip_address}", { :user => vm.user , :keys => [ vm.key ], :paranoid => false, :keys_only => true}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
puts "Executing #{command}"
|
22
|
+
begin
|
23
|
+
session.exec("#{command}") do |ch, stream, data|
|
24
|
+
#exit code
|
25
|
+
#http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/a806b0f5dae4e1e2
|
26
|
+
|
27
|
+
ch.on_request("exit-status") do |ch, data|
|
28
|
+
exit_code = data.read_long
|
29
|
+
@status=exit_code
|
30
|
+
if exit_code > 0
|
31
|
+
puts "ERROR: exit code #{exit_code}"
|
32
|
+
else
|
33
|
+
puts "Successfully executed"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
if (ip2name.count > 1) || options.verbose?
|
37
|
+
puts "[#{ip2name[ch[:host]]}] #{data}"
|
38
|
+
else
|
39
|
+
print "#{data}"
|
40
|
+
end
|
41
|
+
# puts "[#{ch[:host]} : #{stream}] #{data}"
|
42
|
+
|
43
|
+
end
|
44
|
+
rescue Errno::ECONNREFUSED
|
45
|
+
puts "oops - no connection"
|
46
|
+
end
|
47
|
+
# Tell Net::SSH to wait for output from the SSH server
|
48
|
+
session.loop
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'net/scp'
|
2
|
+
|
3
|
+
module Mccloud
|
4
|
+
module Command
|
5
|
+
|
6
|
+
def provision(selection=nil,options=nil)
|
7
|
+
on_selected_machines(selection) do |id,vm|
|
8
|
+
instance=vm.instance
|
9
|
+
instance.private_key_path=vm.key
|
10
|
+
instance.username = vm.user
|
11
|
+
|
12
|
+
#p vm.provisioner
|
13
|
+
provisioner=@session.config.provisioners[vm.provisioner.to_s]
|
14
|
+
if provisioner.nil?
|
15
|
+
# We take the first provisioner defined
|
16
|
+
provisioner=@session.config.provisioners.first[1]
|
17
|
+
end
|
18
|
+
provisioner.run(vm)
|
19
|
+
end
|
20
|
+
##on_selected_machines(selection) do |id,vm|
|
21
|
+
#instance=PROVIDER.servers.get(id)
|
22
|
+
#options={ :port => 22, :keys => [ vm.key ], :paranoid => false, :keys_only => true}
|
23
|
+
#Mccloud::Ssh.execute(instance.public_ip_address,vm.user,options,"who am i")
|
24
|
+
#end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'net/ssh/multi'
|
2
|
+
require 'pp'
|
3
|
+
module Mccloud
|
4
|
+
module Command
|
5
|
+
def server(selection=nil,options=nil)
|
6
|
+
|
7
|
+
trap("INT") { puts "You've hit CTRL-C . Stopping server now"; exit }
|
8
|
+
threads = []
|
9
|
+
on_selected_machines(selection) do |id,vm|
|
10
|
+
threads << Thread.new(id,vm) do |id,vm|
|
11
|
+
public_ip_address=vm.instance.public_ip_address
|
12
|
+
private_ip_address=vm.instance.private_ip_address
|
13
|
+
unless public_ip_address.nil? || private_ip_address.nil?
|
14
|
+
ssh_options={ :keys => [ vm.key ], :paranoid => false, :keys_only => true}
|
15
|
+
Net::SSH.start(public_ip_address, vm.user, ssh_options) do |ssh|
|
16
|
+
vm.forwardings.each do |forwarding|
|
17
|
+
puts "forwarding port #{forwarding.remote} from #{vm.name} to local port #{forwarding.local}"
|
18
|
+
ssh.forward.local(forwarding.local, private_ip_address,forwarding.remote)
|
19
|
+
end
|
20
|
+
ssh.loop { true }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# threads.each {|thr| thr.join}
|
26
|
+
puts "and we continue here"
|
27
|
+
sleep 30
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'mccloud/util/platform'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
module Mccloud
|
5
|
+
module Command
|
6
|
+
def ssh(selection=nil,command=nil,options=nil)
|
7
|
+
if options.screen?
|
8
|
+
extra_command="\"screen -R \\\"#{command}\\\"\""
|
9
|
+
else
|
10
|
+
extra_command="\"#{command}\""
|
11
|
+
end
|
12
|
+
|
13
|
+
if selection.nil?
|
14
|
+
@session.config.vms
|
15
|
+
selection=@session.config.vms.first[0]
|
16
|
+
end
|
17
|
+
|
18
|
+
name=selection
|
19
|
+
vm=@session.config.vms[name]
|
20
|
+
if vm.instance.state != "running"
|
21
|
+
puts "#{name} is not running, move along"
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
#https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/ssh.rb
|
26
|
+
options={ :port => 22, :private_key_path => vm.key,
|
27
|
+
:username => vm.user , :host => vm.instance.public_ip_address }
|
28
|
+
# Command line options
|
29
|
+
command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null",
|
30
|
+
"-t -o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes","-o VerifyHostKeyDNS=no",
|
31
|
+
"-i #{options[:private_key_path]}"]
|
32
|
+
# Some hackery going on here. On Mac OS X Leopard (10.5), exec fails
|
33
|
+
# (GH-51). As a workaround, we fork and wait. On all other platforms,
|
34
|
+
# we simply exec.
|
35
|
+
pid = nil
|
36
|
+
pid = fork if Mccloud::Util::Platform.leopard? || Mccloud::Util::Platform.tiger?
|
37
|
+
|
38
|
+
command_exec="ssh #{command_options.join(" ")} #{options[:username]}@#{options[:host]} #{extra_command}".strip
|
39
|
+
puts "#{command_exec}"
|
40
|
+
Kernel.exec command_exec if pid.nil?
|
41
|
+
Process.wait(pid) if pid
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Mccloud
|
2
|
+
module Command
|
3
|
+
def status(selection=nil,options=nil)
|
4
|
+
|
5
|
+
printf "%-10s %-12s %-20s %-15s %-8s\n", "Name", "Instance Id", "IP", "Type","Status"
|
6
|
+
80.times { |i| printf "=" } ; puts
|
7
|
+
|
8
|
+
unless options.verbose?
|
9
|
+
filter=@session.config.mccloud.prefix
|
10
|
+
else
|
11
|
+
filter=""
|
12
|
+
end
|
13
|
+
|
14
|
+
@session.config.providers.each do |name,provider|
|
15
|
+
provider.servers.each do |vm|
|
16
|
+
name="<no name set>"
|
17
|
+
if !vm.tags["Name"].nil?
|
18
|
+
name=vm.tags["Name"].strip
|
19
|
+
end #end if
|
20
|
+
|
21
|
+
if name.start_with?(filter)
|
22
|
+
unless filter==""
|
23
|
+
name[filter+" - "]=""
|
24
|
+
end
|
25
|
+
printf "%-10s %-12s %-20s %-15s %-8s\n",name,vm.id, vm.public_ip_address, vm.flavor.name,vm.state
|
26
|
+
end
|
27
|
+
end #End 1 provider
|
28
|
+
end #providers
|
29
|
+
end #def
|
30
|
+
end #module
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Mccloud
|
2
|
+
module Command
|
3
|
+
def suspend
|
4
|
+
load_config
|
5
|
+
on_selected_machines(selection) do |id,vm|
|
6
|
+
puts "Halting machine #{vm.name} with Id: #{id}"
|
7
|
+
PROVIDER.servers.get(id).stop
|
8
|
+
|
9
|
+
vm.instance.wait_for { printf ".";STDOUT.flush; state=="stopped"}
|
10
|
+
puts
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'mccloud/util/iterator'
|
3
|
+
|
4
|
+
module Mccloud
|
5
|
+
module Command
|
6
|
+
include Mccloud::Util
|
7
|
+
def up(selection,options)
|
8
|
+
|
9
|
+
on_selected_machines(selection) do |id,vm|
|
10
|
+
|
11
|
+
provider=@session.config.providers[vm.provider]
|
12
|
+
if (id.nil?)
|
13
|
+
puts "Machine #{vm.name} doesn't yet exist"
|
14
|
+
provider_options=vm.provider_options
|
15
|
+
boxname=vm.name
|
16
|
+
puts "Spinning up a new machine called #{boxname}"
|
17
|
+
instance=provider.servers.create(provider_options)
|
18
|
+
puts "Waiting for it the machine to become accessible"
|
19
|
+
instance.wait_for { printf "."; STDOUT.flush; ready?}
|
20
|
+
puts
|
21
|
+
prefix=@session.config.mccloud.prefix
|
22
|
+
|
23
|
+
|
24
|
+
provider.create_tags(instance.id, { "Name" => "#{prefix} - #{boxname}"})
|
25
|
+
|
26
|
+
# Resetting the in memory model of the new machine
|
27
|
+
@all_servers[boxname.to_s]=instance.id
|
28
|
+
unless @session.config.vms[boxname.to_s].nil?
|
29
|
+
@session.config.vms[boxname.to_s].reload
|
30
|
+
end
|
31
|
+
|
32
|
+
# Wait for ssh to become available ...
|
33
|
+
puts "Waiting for ssh to be come available"
|
34
|
+
Mccloud::Util.execute_when_tcp_available(instance.public_ip_address, { :port => 22, :timeout => 60 }) do
|
35
|
+
puts "Ok, ssh is available , proceeding with bootstrap"
|
36
|
+
end
|
37
|
+
|
38
|
+
@session.bootstrap(boxname.to_s,nil,options)
|
39
|
+
|
40
|
+
else
|
41
|
+
state=vm.instance.state
|
42
|
+
if state =="stopped"
|
43
|
+
puts "Machine #{vm.name} was stopped -> starting it again"
|
44
|
+
vm.instance.start
|
45
|
+
vm.instance.wait_for { printf ".";STDOUT.flush; ready?}
|
46
|
+
puts
|
47
|
+
else
|
48
|
+
puts "Machine #{selection} already exists but is currently in state #{state} "
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
@session.provision(selection,options)
|
56
|
+
|
57
|
+
#server.boostrap(:image_id => 'ami', :private_key_path => '', :public_key_path => '')
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'mccloud/configurator/mccloud'
|
2
|
+
require 'mccloud/configurator/vm'
|
3
|
+
require 'mccloud/configurator/lb'
|
4
|
+
require 'mccloud/provisioner/chef_solo'
|
5
|
+
|
6
|
+
module Mccloud
|
7
|
+
|
8
|
+
class Configuration
|
9
|
+
attr_accessor :vms
|
10
|
+
attr_accessor :lbs
|
11
|
+
attr_accessor :providers
|
12
|
+
attr_accessor :provisioners
|
13
|
+
|
14
|
+
attr_accessor :mccloud
|
15
|
+
attr_accessor :vm
|
16
|
+
attr_accessor :lb
|
17
|
+
attr_accessor :session
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@vms=Hash.new
|
21
|
+
@lbs=Hash.new
|
22
|
+
@providers=Hash.new
|
23
|
+
@vm=Mccloud::Configurator::VmConfigurator.new
|
24
|
+
@lb=Mccloud::Configurator::LbConfigurator.new
|
25
|
+
@mccloud=Mccloud::Configurator::MccloudConfigurator.new
|
26
|
+
@provisioners=Hash.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Config
|
31
|
+
class << self;
|
32
|
+
attr_accessor :config
|
33
|
+
end
|
34
|
+
def self.run
|
35
|
+
@config=Configuration.new
|
36
|
+
|
37
|
+
# Here we access a global thing, TODO to make it session specific
|
38
|
+
|
39
|
+
Mccloud.session.config=@config
|
40
|
+
yield @config
|
41
|
+
#Resetting any left over
|
42
|
+
|
43
|
+
@config.vm=nil
|
44
|
+
@config.lb=nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'mccloud/provisioner/chef_solo'
|
2
|
+
require 'mccloud/provisioner/puppet'
|
3
|
+
|
4
|
+
require 'mccloud/type/lb'
|
5
|
+
|
6
|
+
module Mccloud
|
7
|
+
module Configurator
|
8
|
+
|
9
|
+
class LbConfigurator
|
10
|
+
|
11
|
+
attr_accessor :lb
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
end
|
15
|
+
|
16
|
+
def define(name)
|
17
|
+
@lb=Mccloud::Type::Lb.new
|
18
|
+
lbconfig=self
|
19
|
+
yield lbconfig
|
20
|
+
@lb.name=name
|
21
|
+
Mccloud.session.config.lbs[name.to_s]=@lb
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end #Module Mccloud
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'mccloud/provisioner/chef_solo'
|
2
|
+
require 'mccloud/provisioner/puppet'
|
3
|
+
|
4
|
+
require 'mccloud/type/vm'
|
5
|
+
|
6
|
+
module Mccloud
|
7
|
+
module Configurator
|
8
|
+
|
9
|
+
class VmConfigurator
|
10
|
+
|
11
|
+
attr_accessor :vm
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
end
|
15
|
+
|
16
|
+
def define(name)
|
17
|
+
@vm=Mccloud::Type::Vm.new
|
18
|
+
vmconfig=self
|
19
|
+
yield vmconfig
|
20
|
+
@vm.name=name
|
21
|
+
Mccloud.session.config.vms[name.to_s]=@vm
|
22
|
+
end
|
23
|
+
def provision(type)
|
24
|
+
case type
|
25
|
+
when :chef_solo
|
26
|
+
@provisioner=Mccloud::Provisioner::ChefSolo.new
|
27
|
+
when :puppet
|
28
|
+
@provisioner=Mccloud::Provisioner::Puppet.new
|
29
|
+
else
|
30
|
+
end
|
31
|
+
yield @provisioner
|
32
|
+
Mccloud.session.config.provisioners[type.to_s]=@provisioner
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end #Module Mccloud
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'templater'
|
2
|
+
|
3
|
+
module Mccloud
|
4
|
+
module Generators
|
5
|
+
extend Templater::Manifold
|
6
|
+
|
7
|
+
class InitGenerator < Templater::Generator
|
8
|
+
def self.source_root
|
9
|
+
File.join(File.dirname(__FILE__), 'templates')
|
10
|
+
end
|
11
|
+
|
12
|
+
desc <<-DESC
|
13
|
+
Initialize a mccloud environment
|
14
|
+
mccloud init [AMI-ID]
|
15
|
+
DESC
|
16
|
+
|
17
|
+
first_argument :ami_id, :required => true, :desc => 'AMI ID'
|
18
|
+
|
19
|
+
template :mccloudfile, 'Mccloudfile'
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Generators to simplify the creation of a Mccloud Project"
|
24
|
+
add :init, InitGenerator
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|