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,44 @@
|
|
1
|
+
Mccloud::Config.run do |config|
|
2
|
+
# All Mccloud configuration is done here. For a detailed explanation
|
3
|
+
# and listing of configuration options, please view the documentation
|
4
|
+
# online.
|
5
|
+
|
6
|
+
config.mccloud.prefix="mccloud"
|
7
|
+
|
8
|
+
config.vm.define :web do |web_config|
|
9
|
+
web_config.vm.ami = "ami-cef405a7"
|
10
|
+
web_config.vm.provider="AWS"
|
11
|
+
|
12
|
+
#web_config.vm.provisioner=:chef_solo
|
13
|
+
#web_config.vm.provisioner=:puppet
|
14
|
+
|
15
|
+
web_config.vm.provider_options={
|
16
|
+
# ID = "ami-cef405a7" = x64 Ubuntu 10.10
|
17
|
+
:image_id => 'ami-cef405a7',
|
18
|
+
# Flavors
|
19
|
+
:flavor_id => 't1.micro',
|
20
|
+
#:flavor_id => 'm1.large',
|
21
|
+
:groups => %w(ec2securitygroup), :key_name => "ec2-keyname",
|
22
|
+
:availability_zone => "us-east-1b"
|
23
|
+
}
|
24
|
+
web_config.vm.forward_port("http", 80, 8080)
|
25
|
+
web_config.vm.user="ubuntu"
|
26
|
+
web_config.vm.bootstrap="ruby-bootstrap.sh"
|
27
|
+
web_config.vm.key="my-ec2-key.pem"
|
28
|
+
end
|
29
|
+
|
30
|
+
### Provisioners
|
31
|
+
config.vm.provision :puppet do |puppet|
|
32
|
+
puppet.pp_path = "/tmp/vagrant-puppet"
|
33
|
+
#puppet.manifests_path = "puppet/manifests"
|
34
|
+
#puppet.module_path = "puppet/modules"
|
35
|
+
puppet.manifest_file = "newbox.pp"
|
36
|
+
end
|
37
|
+
|
38
|
+
config.vm.provision :chef_solo do |chef|
|
39
|
+
chef.cookbooks_path = ["<your cookboopath>"]
|
40
|
+
chef.add_recipe("<some recipe>")
|
41
|
+
# You may also specify custom JSON attributes:
|
42
|
+
chef.json.merge!({})
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'mccloud/type/forwarding'
|
2
|
+
module Mccloud
|
3
|
+
module Type
|
4
|
+
|
5
|
+
class Lb
|
6
|
+
attr_accessor :provider
|
7
|
+
attr_accessor :provider_options
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
attr_accessor :members
|
11
|
+
|
12
|
+
attr_accessor :instance
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
end
|
16
|
+
|
17
|
+
def instance
|
18
|
+
if @this_instance.nil?
|
19
|
+
begin
|
20
|
+
@this_instance=Mccloud.session.config.providers[provider].servers.get(Mccloud.session.all_servers[name.to_s])
|
21
|
+
rescue Fog::Service::Error => e
|
22
|
+
puts "Error: #{e.message}"
|
23
|
+
puts "We could not request the information from your provider #{provider}. We suggest you check your credentials."
|
24
|
+
puts "Check configuration file: #{File.join(ENV['HOME'],".fog")}"
|
25
|
+
exit -1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return @this_instance
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end #Module Mccloud
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'mccloud/type/forwarding'
|
2
|
+
module Mccloud
|
3
|
+
module Type
|
4
|
+
|
5
|
+
class Vm
|
6
|
+
attr_accessor :ami
|
7
|
+
attr_accessor :provider
|
8
|
+
attr_accessor :provider_options
|
9
|
+
attr_accessor :name
|
10
|
+
attr_accessor :user
|
11
|
+
attr_accessor :key
|
12
|
+
attr_accessor :bootstrap
|
13
|
+
attr_accessor :provisioner
|
14
|
+
attr_accessor :forwardings
|
15
|
+
|
16
|
+
attr_accessor :instance
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@forwardings=Array.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def instance
|
23
|
+
if @this_instance.nil?
|
24
|
+
begin
|
25
|
+
@this_instance=Mccloud.session.config.providers[provider].servers.get(Mccloud.session.all_servers[name.to_s])
|
26
|
+
rescue Fog::Service::Error => e
|
27
|
+
puts "Error: #{e.message}"
|
28
|
+
puts "We could not request the information from your provider #{provider}. We suggest you check your credentials."
|
29
|
+
puts "Check configuration file: #{File.join(ENV['HOME'],".fog")}"
|
30
|
+
exit -1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return @this_instance
|
34
|
+
end
|
35
|
+
|
36
|
+
def reload
|
37
|
+
@this_instance=nil
|
38
|
+
end
|
39
|
+
def forward_port(name,local,remote)
|
40
|
+
forwarding=Forwarding.new(name,local,remote)
|
41
|
+
forwardings << forwarding
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end #Module Mccloud
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'pp'
|
2
|
+
module Mccloud
|
3
|
+
module Util
|
4
|
+
def on_selected_machines(selection=nil)
|
5
|
+
if selection.nil? || selection == "all"
|
6
|
+
puts "no selection - all machines"
|
7
|
+
@session.config.vms.each do |name,vm|
|
8
|
+
id=@all_servers["#{name}"]
|
9
|
+
vm=@session.config.vms[name]
|
10
|
+
yield id,vm
|
11
|
+
|
12
|
+
end
|
13
|
+
else
|
14
|
+
name=selection
|
15
|
+
id=@all_servers["#{name}"]
|
16
|
+
vm=@session.config.vms[name]
|
17
|
+
yield id,vm
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
#Shameless copy of Vagrant code
|
4
|
+
module Mccloud
|
5
|
+
module Util
|
6
|
+
# This class just contains some platform checking code.
|
7
|
+
class Platform
|
8
|
+
class << self
|
9
|
+
def tiger?
|
10
|
+
platform.include?("darwin8")
|
11
|
+
end
|
12
|
+
|
13
|
+
def leopard?
|
14
|
+
platform.include?("darwin9")
|
15
|
+
end
|
16
|
+
|
17
|
+
[:darwin, :bsd, :linux].each do |type|
|
18
|
+
define_method("#{type}?") do
|
19
|
+
platform.include?(type.to_s)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def platform
|
24
|
+
RbConfig::CONFIG["host_os"].downcase
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "pty"
|
2
|
+
module Mccloud
|
3
|
+
module Util
|
4
|
+
def self.rsync(path,vm,instance)
|
5
|
+
command="rsync --delete -avz -e 'ssh -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i \"#{vm.key}\"' '#{path}/' '#{vm.user}@#{instance.public_ip_address}:/tmp/#{File.basename(path)}/'"
|
6
|
+
puts command
|
7
|
+
begin
|
8
|
+
PTY.spawn( command ) do |r, w, pid|
|
9
|
+
begin
|
10
|
+
r.each { |line| print line;}
|
11
|
+
rescue Errno::EIO
|
12
|
+
end
|
13
|
+
end
|
14
|
+
rescue PTY::ChildExited => e
|
15
|
+
puts "The child process exited!"
|
16
|
+
end
|
17
|
+
#Kernel.exec(command)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module Mccloud
|
2
|
+
module Util
|
3
|
+
|
4
|
+
def self.when_ssh_login_works(ip="localhost", options = { } , &block)
|
5
|
+
|
6
|
+
defaults={ :port => '22', :timeout => 200 , :user => 'vagrant', :password => 'vagrant'}
|
7
|
+
|
8
|
+
options=defaults.merge(options)
|
9
|
+
|
10
|
+
puts
|
11
|
+
puts "Waiting for ssh login with user #{options[:user]} to sshd on port => #{options[:port]} to work"
|
12
|
+
|
13
|
+
begin
|
14
|
+
Timeout::timeout(options[:timeout]) do
|
15
|
+
connected=false
|
16
|
+
while !connected do
|
17
|
+
begin
|
18
|
+
print "."
|
19
|
+
Net::SSH.start(ip, options[:user], { :port => options[:port] , :password => options[:password], :paranoid => false, :timeout => options[:timeout] }) do |ssh|
|
20
|
+
block.call(ip);
|
21
|
+
puts ""
|
22
|
+
return true
|
23
|
+
end
|
24
|
+
rescue Net::SSH::Disconnect,Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::ENETUNREACH
|
25
|
+
sleep 5
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue Timeout::Error
|
30
|
+
raise 'ssh timeout'
|
31
|
+
end
|
32
|
+
puts ""
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def self.transfer_file(host,filename,destination = '.' , options = {})
|
38
|
+
|
39
|
+
Net::SSH.start( host,options[:user],options ) do |ssh|
|
40
|
+
puts "Transferring #{filename} to #{destination} "
|
41
|
+
ssh.scp.upload!( filename, destination ) do |ch, name, sent, total|
|
42
|
+
# print "\r#{destination}: #{(sent.to_f * 100 / total.to_f).to_i}%"
|
43
|
+
print "."
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
puts
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
#we need to try the actual login because vbox gives us a connect
|
52
|
+
#after the machine boots
|
53
|
+
def self.execute_when_tcp_available(ip="localhost", options = { } , &block)
|
54
|
+
|
55
|
+
defaults={ :port => 22, :timeout => 2 , :pollrate => 5}
|
56
|
+
|
57
|
+
options=defaults.merge(options)
|
58
|
+
|
59
|
+
begin
|
60
|
+
Timeout::timeout(options[:timeout]) do
|
61
|
+
connected=false
|
62
|
+
while !connected do
|
63
|
+
begin
|
64
|
+
#puts "trying connection"
|
65
|
+
s = TCPSocket.new(ip, options[:port])
|
66
|
+
s.close
|
67
|
+
block.call(ip);
|
68
|
+
return true
|
69
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
70
|
+
sleep options[:pollrate]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
rescue Timeout::Error
|
75
|
+
raise 'timeout connecting to port'
|
76
|
+
end
|
77
|
+
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.ssh(host ,user , options = { :progress => "on" } ,command=nil ,exitcode=0)
|
82
|
+
|
83
|
+
defaults= { :port => "22", :user => "root", :paranoid => false }
|
84
|
+
options=defaults.merge(options)
|
85
|
+
@pid=""
|
86
|
+
@stdin=command
|
87
|
+
@stdout=""
|
88
|
+
@stderr=""
|
89
|
+
@status=-99999
|
90
|
+
|
91
|
+
puts "Executing command: #{command}"
|
92
|
+
|
93
|
+
Net::SSH.start(host, user, options) do |ssh|
|
94
|
+
|
95
|
+
# open a new channel and configure a minimal set of callbacks, then run
|
96
|
+
# the event loop until the channel finishes (closes)
|
97
|
+
channel = ssh.open_channel do |ch|
|
98
|
+
|
99
|
+
#request pty for sudo stuff and so
|
100
|
+
ch.request_pty do |ch, success|
|
101
|
+
raise "Error requesting pty" unless success
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
ch.exec "#{command}" do |ch, success|
|
106
|
+
raise "could not execute command" unless success
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
# "on_data" is called when the process writes something to stdout
|
111
|
+
ch.on_data do |c, data|
|
112
|
+
@stdout+=data
|
113
|
+
|
114
|
+
puts data
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
# "on_extended_data" is called when the process writes something to stderr
|
119
|
+
ch.on_extended_data do |c, type, data|
|
120
|
+
@stderr+=data
|
121
|
+
|
122
|
+
puts data
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
#exit code
|
127
|
+
#http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/a806b0f5dae4e1e2
|
128
|
+
channel.on_request("exit-status") do |ch, data|
|
129
|
+
exit_code = data.read_long
|
130
|
+
@status=exit_code
|
131
|
+
if exit_code > 0
|
132
|
+
puts "ERROR: exit code #{exit_code}"
|
133
|
+
else
|
134
|
+
#puts "Successfully executed"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
channel.on_request("exit-signal") do |ch, data|
|
139
|
+
puts "SIGNAL: #{data.read_long}"
|
140
|
+
end
|
141
|
+
|
142
|
+
ch.on_close {
|
143
|
+
#puts "done!"
|
144
|
+
}
|
145
|
+
#status=ch.exec "echo $?"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
channel.wait
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
if (@status.to_s != exitcode.to_s )
|
153
|
+
if (exitcode=="*")
|
154
|
+
#its a test so we don't need to worry
|
155
|
+
else
|
156
|
+
puts "Exitcode = #{exitcode} - #{@status.to_s}"
|
157
|
+
raise "Exitcode was not what we expected"
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
end #Class
|
167
|
+
end #Module
|
data/mccloud.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/mccloud/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "mccloud"
|
6
|
+
s.version = Mccloud::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Patrick Debois"]
|
9
|
+
s.email = ["patrick.debois@jedi.be"]
|
10
|
+
s.homepage = "http://github.com/jedi4ever/mccloud/"
|
11
|
+
s.summary = %q{Cloud integration vagrant style}
|
12
|
+
s.description = %q{Use the same simple commandline api to manage cloud interfaces}
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
s.rubyforge_project = "mccloud"
|
16
|
+
|
17
|
+
s.add_dependency "net-ssh", "~> 2.1.0"
|
18
|
+
s.add_dependency "net-scp"
|
19
|
+
s.add_dependency "fog"
|
20
|
+
s.add_dependency "json"
|
21
|
+
s.add_dependency "templater"
|
22
|
+
s.add_dependency "popen4", "~> 0.1.2"
|
23
|
+
s.add_dependency "thor", "~> 0.14.6"
|
24
|
+
s.add_dependency "highline", "~> 1.6.1"
|
25
|
+
s.add_dependency "progressbar"
|
26
|
+
s.add_dependency "cucumber", "0.8.5"
|
27
|
+
|
28
|
+
s.add_dependency "net-ssh-multi"
|
29
|
+
#s.add_dependency "rspec"
|
30
|
+
|
31
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
32
|
+
|
33
|
+
s.files = `git ls-files`.split("\n")
|
34
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
35
|
+
s.require_path = 'lib'
|
36
|
+
end
|
37
|
+
|
data/ruby-bootstrap.sh
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/bin/bash -ex
|
2
|
+
|
3
|
+
apt-get update
|
4
|
+
apt-get -y install ruby ruby-dev libopenssl-ruby rdoc ri irb build-essential wget ssl-cert
|
5
|
+
cd /tmp
|
6
|
+
test ! -f rubygems-1.3.7 && wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
|
7
|
+
test -f rubygems-1.3.7.tgz && tar zxf rubygems-1.3.7.tgz
|
8
|
+
cd rubygems-1.3.7 && ruby setup.rb --no-format-executable
|
9
|
+
gem install chef --no-ri --no-rdoc
|
10
|
+
gem install puppet --no-ri --no-rdoc
|
11
|
+
|
data/ruby-bootstrap2.sh
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/bin/bash -ex
|
2
|
+
|
3
|
+
# redirecting output
|
4
|
+
# http://alestic.com/2010/12/ec2-user-data-output
|
5
|
+
#exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
|
6
|
+
|
7
|
+
apt-get -y update
|
8
|
+
apt-get -y upgrade
|
9
|
+
apt-get -y dist-upgrade
|
10
|
+
|
11
|
+
apt-get -y install git
|
12
|
+
|
13
|
+
# For CC compiler of ruby
|
14
|
+
apt-get -y install build-essential
|
15
|
+
|
16
|
+
# no such file to load -- zlib (LoadError)
|
17
|
+
# http://stackoverflow.com/questions/2441248/rvm-ruby-1-9-1-troubles
|
18
|
+
apt-get install -y zlib1g-dev libssl-dev libreadline5-dev libxml2-dev libsqlite3-dev
|
19
|
+
|
20
|
+
> /tmp/base-finished
|
21
|
+
|
22
|
+
#/.rvm/src/rvm/scripts/install: line 243: HOME: unbound variable
|
23
|
+
HOME="/root"
|
24
|
+
export HOME
|
25
|
+
|
26
|
+
# RVM
|
27
|
+
# http://rvm.beginrescueend.com/
|
28
|
+
#bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
|
29
|
+
bash < <( curl -L http://bit.ly/rvm-install-system-wide )
|
30
|
+
|
31
|
+
echo ". /usr/local/rvm" >> /etc/profile.d/rvm-system-wide
|
32
|
+
|
33
|
+
#
|
34
|
+
#[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
|
35
|
+
. /usr/local/rvm/scripts/rvm
|
36
|
+
|
37
|
+
rvm install 1.9.2
|
38
|
+
rvm use 1.9.2 --default
|
39
|
+
|