mccloud 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +4 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +74 -0
  5. data/README.md +123 -0
  6. data/Rakefile +5 -0
  7. data/bin/mccloud +116 -0
  8. data/lib/mccloud.rb +2 -0
  9. data/lib/mccloud/command/boot.rb +12 -0
  10. data/lib/mccloud/command/bootstrap.rb +31 -0
  11. data/lib/mccloud/command/command.rb +21 -0
  12. data/lib/mccloud/command/destroy.rb +19 -0
  13. data/lib/mccloud/command/halt.rb +19 -0
  14. data/lib/mccloud/command/init.rb +7 -0
  15. data/lib/mccloud/command/multi.rb +53 -0
  16. data/lib/mccloud/command/provision.rb +28 -0
  17. data/lib/mccloud/command/reload.rb +11 -0
  18. data/lib/mccloud/command/server.rb +30 -0
  19. data/lib/mccloud/command/ssh.rb +46 -0
  20. data/lib/mccloud/command/status.rb +31 -0
  21. data/lib/mccloud/command/suspend.rb +15 -0
  22. data/lib/mccloud/command/up.rb +65 -0
  23. data/lib/mccloud/config.rb +47 -0
  24. data/lib/mccloud/configurator/lb.rb +26 -0
  25. data/lib/mccloud/configurator/mccloud.rb +13 -0
  26. data/lib/mccloud/configurator/vm.rb +37 -0
  27. data/lib/mccloud/generators.rb +28 -0
  28. data/lib/mccloud/provisioner/chef_solo.rb +149 -0
  29. data/lib/mccloud/provisioner/puppet.rb +39 -0
  30. data/lib/mccloud/provisioner/vagrant/base.rb +63 -0
  31. data/lib/mccloud/provisioner/vagrant/chef.rb +130 -0
  32. data/lib/mccloud/provisioner/vagrant/chef_server.rb +103 -0
  33. data/lib/mccloud/provisioner/vagrant/chef_solo.rb +142 -0
  34. data/lib/mccloud/provisioner/vagrant/puppet.rb +137 -0
  35. data/lib/mccloud/provisioner/vagrant/puppet_server.rb +55 -0
  36. data/lib/mccloud/provisioner/vagrant/shell.rb +52 -0
  37. data/lib/mccloud/session.rb +199 -0
  38. data/lib/mccloud/templates/Mccloudfilet +44 -0
  39. data/lib/mccloud/type/forwarding.rb +11 -0
  40. data/lib/mccloud/type/lb.rb +34 -0
  41. data/lib/mccloud/type/vm.rb +46 -0
  42. data/lib/mccloud/util/iterator.rb +21 -0
  43. data/lib/mccloud/util/platform.rb +29 -0
  44. data/lib/mccloud/util/rsync.rb +21 -0
  45. data/lib/mccloud/util/ssh.rb +167 -0
  46. data/lib/mccloud/version.rb +3 -0
  47. data/mccloud.gemspec +37 -0
  48. data/ruby-bootstrap.sh +11 -0
  49. data/ruby-bootstrap2.sh +39 -0
  50. metadata +297 -0
@@ -0,0 +1,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,11 @@
1
+ class Forwarding
2
+ attr_accessor :name
3
+ attr_accessor :local
4
+ attr_accessor :remote
5
+
6
+ def initialize(name,local,remote)
7
+ @name=name
8
+ @local=local
9
+ @remote=remote
10
+ end
11
+ 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
@@ -0,0 +1,3 @@
1
+ module Mccloud
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
+
@@ -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
+
@@ -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
+