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,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
|
+
|