pupcap 0.0.1 → 0.0.2

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/lib/pupcap/action.rb CHANGED
@@ -5,49 +5,57 @@ require 'capistrano/cli'
5
5
  module Pupcap::Action
6
6
  class Base
7
7
 
8
- def initialize(file, options = {})
9
- @file = file
10
- @options = options
11
- set_default_vars
12
- ENV["ROLES"] = @options[:role]
8
+ def parsed_options
9
+ {}
13
10
  end
14
11
 
15
-
16
- class << self
17
- def ensure_local_dir(dir, mode = "0755")
18
- run_local("mkdir -p #{dir} && chmod #{mode} #{dir}")
12
+ def check_puppetfile!
13
+ unless File.exists?(parsed_options[:file])
14
+ $stderr.puts "File #{parsed_options[:file]} does not exists"
15
+ exit 1
19
16
  end
17
+ end
20
18
 
21
- def run_local(cmd)
22
- system cmd
23
- fail "#{cmd} fail" if $?.to_i != 0
19
+ def check_role!
20
+ unless parsed_options[:role]
21
+ $stderr.puts "Please specify role"
22
+ exit 1
24
23
  end
25
24
  end
26
25
 
27
- def load_recipes(config) #:nodoc:
28
- # load the standard recipe definition
29
- cap.load "standard"
26
+ def create_cap_for(file)
27
+ cap = Capistrano::Configuration.new
28
+ cap.logger.level = Capistrano::Logger::DEBUG
29
+ set_cap_vars!(cap, file)
30
+ cap.load file
31
+ cap
32
+ end
33
+
34
+ def lib_root
35
+ File.dirname(File.expand_path __FILE__) + "/action"
36
+ end
37
+
38
+ def cap_load_and_run_task(cap, task)
39
+ cap.set :pupcap_options, parsed_options
40
+ cap.load "#{lib_root}/#{task}/Capfile"
41
+ cap.trigger(:load)
42
+ cap.find_and_execute_task(task, :before => :start, :after => :finish)
43
+ cap.trigger(:exit)
30
44
  end
31
45
 
32
46
  private
33
- def set_default_vars
34
- app = ENV['app'] || File.basename(File.dirname(@file))
47
+
48
+ def set_cap_vars!(cap, file)
49
+ app = ENV['app'] || File.basename(File.dirname(file))
35
50
  cap.set :application, app
36
- cap.set :local_root, File.dirname(@file)
51
+ cap.set :local_root, File.dirname(file)
37
52
  cap.set :provision_key, "#{cap.local_root}/.keys/provision"
38
53
  cap.set :provision_key_pub, "#{cap.local_root}/.keys/provision.pub"
54
+ cap.set :deploy_to, "/tmp/puppet"
39
55
  cap.ssh_options[:keys] = cap.provision_key
40
56
  cap.ssh_options[:forward_agent] = true
41
57
  cap.default_run_options[:pty] = true
42
- cap.load @file
43
- end
44
-
45
- def cap
46
- unless @cap
47
- @cap = Capistrano::Configuration.new
48
- @cap.logger.level = Capistrano::Logger::DEBUG
49
- end
50
- @cap
58
+ cap
51
59
  end
52
60
  end
53
61
  end
@@ -1,14 +1,52 @@
1
1
  require 'pupcap/action'
2
+ require 'pupcap/command'
2
3
 
3
4
  class Pupcap::Action::Cook < Pupcap::Action::Base
5
+ def initialize
6
+ check_role!
7
+ check_puppetfile!
8
+ ENV["ROLES"] = parsed_options[:role]
9
+ end
10
+
4
11
  def start
5
- cap.load "#{root}/cook/Capfile"
6
- cap.trigger(:load)
7
- cap.find_and_execute_task("cook", :before => :start, :after => :finish)
8
- cap.trigger(:exit)
12
+ cap = create_cap_for(parsed_options[:file])
13
+ cap_load_and_run_task(cap, "cook")
14
+ end
15
+
16
+ def parsed_options
17
+ unless @parsed_options
18
+ options = default_options.dup
19
+ OptionParser.new do |opts|
20
+ opts.banner = "Usage: #{File.basename($0)} [options] <role> cook"
21
+
22
+ opts.on("-f", "--file FILE", "A recipe file to load") do |file|
23
+ options[:file] = File.expand_path(file)
24
+ end
25
+
26
+ opts.on("-h", "--help", "Displays this help info") do
27
+ puts opts
28
+ exit 0
29
+ end
30
+
31
+ opts.on("-d", "--debug", "Debug output") do
32
+ options[:debug] = true
33
+ end
34
+
35
+ opts.on("-n", "--noop", "Noop") do |file|
36
+ options[:noop] = true
37
+ end
38
+ end.parse!
39
+ options[:role] = ARGV.first
40
+ @parsed_options = options
41
+ end
42
+ @parsed_options
9
43
  end
10
44
 
11
- def root
12
- File.dirname(File.expand_path __FILE__)
45
+ def default_options
46
+ {
47
+ :file => File.expand_path("Puppetfile"),
48
+ :debug => false,
49
+ :noop => false
50
+ }
13
51
  end
14
52
  end
@@ -1,26 +1,30 @@
1
1
  namespace :cook do
2
2
  task :default do
3
- remote_path = "/tmp/puppet"
3
+ rsync
4
+ apply
5
+ cleanup
6
+ end
7
+
8
+ task :rsync do
4
9
  find_servers.each do |server|
5
- ssh_cmd = "-e \"ssh -p #{cook_ssh_port(server)} -i #{provision_key}\""
6
- rsync_options = "-p --chmod=o+r,g+r -az --exclude=\".keys/\""
7
- rsync_path = "--rsync-path=\"sudo rsync\""
8
- cmd = "rsync #{rsync_options} #{ssh_cmd} #{local_root}/ #{rsync_path} #{cook_rsync_host(server)}:#{remote_path}"
10
+ port = Pupcap::Command.server_port(self, server)
11
+ host = Pupcap::Command.server_host(self, server)
12
+ ssh_cmd = "-e \"ssh -p #{port} -i #{provision_key}\""
13
+ rsync_options = "-p --chmod=o+r,g+r -az"
14
+ cmd = "rsync #{rsync_options} #{ssh_cmd} #{local_root}/ #{host}:#{deploy_to}"
9
15
  logger.important(cmd)
10
16
  system(cmd)
11
17
  end
12
- modules = "--modulepath=#{remote_path}/modules:#{remote_path}/manifests"
13
- nook = ENV["try"] ? "--noop" : ""
14
- debug = ENV["debug"] ? "--debug" : ""
15
- sudo("/usr/local/bin/puppet apply --detailed-exitcodes #{nook} #{debug} #{modules} #{remote_path}/manifests/#{ENV["ROLES"]}.pp || true")
16
18
  end
17
19
 
18
- def cook_ssh_port(server)
19
- server.port || ssh_options[:port] || 22
20
+ task :apply do
21
+ modules = "--modulepath=#{deploy_to}/modules:#{deploy_to}/manifests"
22
+ nook = pupcap_options[:noop] ? "--noop" : ""
23
+ debug = pupcap_options[:debug] ? "--debug" : ""
24
+ sudo("/usr/local/bin/puppet apply --detailed-exitcodes #{nook} #{debug} #{modules} #{deploy_to}/manifests/#{ENV["ROLES"]}.pp || true")
20
25
  end
21
26
 
22
- def cook_rsync_host(server)
23
- u = server.user || fetch(:user)
24
- u ? "#{u}@#{server.host}" : server.host
27
+ task :cleanup do
28
+ run("rm -rf #{deploy_to}")
25
29
  end
26
30
  end
@@ -1,28 +1,54 @@
1
1
  require 'pupcap/action'
2
+ require 'pupcap/lsb_release'
2
3
 
3
4
  class Pupcap::Action::Prepare < Pupcap::Action::Base
4
- def start
5
- cap.load "#{root}/prepare/Capfile"
6
- cap.trigger(:load)
7
- cap.find_and_execute_task("prepare", :before => :start, :after => :finish)
8
- prepare_dist
9
- cap.trigger(:exit)
5
+ def initialize
6
+ check_role!
7
+ check_puppetfile!
8
+ ENV["ROLES"] = parsed_options[:role]
10
9
  end
11
10
 
12
- def root
13
- File.dirname(File.expand_path __FILE__)
11
+ def start
12
+ cap = create_cap_for(parsed_options[:file])
13
+ lsb = Pupcap::LsbRelease.new(cap)
14
+ prepare_script = "#{lib_root}/prepare/#{lsb.name.downcase}/#{lsb.codename.downcase}.sh"
15
+ if File.exists?(prepare_script)
16
+ cap.set :pupcap_prepare_script, prepare_script
17
+ end
18
+ cap_load_and_run_task(cap, "prepare")
14
19
  end
15
20
 
16
- def prepare_dist
17
- rel = cap.capture("lsb_release -d")
18
- codename = rel.match(/^.*:\s(.*)$/)
19
- if codename && codename[1]
20
- codename = codename[1].to_s.strip[0...12]
21
- case codename
22
- when 'Ubuntu 12.04'
23
- cap.load "#{root}/prepare/ubuntu/precise.rb"
24
- cap.find_and_execute_task("prepare:ubuntu:precise")
25
- end
21
+ def parsed_options
22
+ unless @parsed_options
23
+ options = default_options.dup
24
+ OptionParser.new do |opts|
25
+ opts.banner = "Usage: #{File.basename($0)} [options] <role> prepare"
26
+
27
+ opts.on("-h", "--help", "Displays this help info") do
28
+ puts opts
29
+ exit 0
30
+ end
31
+
32
+ opts.on("-F", "--force", "Force prepare") do
33
+ options[:force] = true
34
+ end
35
+
36
+ opts.on("-f", "--file FILE", "A recipe file to load") do |file|
37
+ options[:file] = File.expand_path(file)
38
+ end
39
+ end.parse!
40
+ options[:role] = ARGV.first
41
+ @parsed_options = options
26
42
  end
43
+ @parsed_options
44
+ end
45
+
46
+ def default_options
47
+ {
48
+ :file => File.expand_path("Puppetfile"),
49
+ :force => false,
50
+ :upgrade => false
51
+ }
27
52
  end
28
53
  end
54
+
@@ -2,6 +2,7 @@ namespace :prepare do
2
2
  task :default do
3
3
  generate_keys
4
4
  ssh_copy_id
5
+ run_script
5
6
  end
6
7
 
7
8
  task :ssh_copy_id do
@@ -15,10 +16,21 @@ namespace :prepare do
15
16
  task :generate_keys do
16
17
  unless File.exists?(provision_key)
17
18
  logger.important("Generate keys")
18
- Pupcap::Action.ensure_local_dir("#{local_root}/.keys", "0700")
19
- Pupcap::Action.run_local("ssh-keygen -q -b 1024 -t rsa -C \"#{application} provision key\" -f #{provision_key}")
20
- Pupcap::Action.run_local("chmod 0600 #{provision_key}")
21
- Pupcap::Action.run_local("chmod 0600 #{provision_key_pub}")
19
+ Pupcap::Command.ensure_local_dir("#{local_root}/.keys", "0700")
20
+ Pupcap::Command.run_local("ssh-keygen -q -b 1024 -t rsa -C \"#{application} provision key\" -f #{provision_key}")
21
+ Pupcap::Command.run_local("chmod 0600 #{provision_key}")
22
+ Pupcap::Command.run_local("chmod 0600 #{provision_key_pub}")
23
+ end
24
+ end
25
+
26
+ task :run_script do
27
+ if exists?(:pupcap_prepare_script)
28
+ remote_script_name = "/tmp/pupcap_prepare.#{Time.now.to_i}.sh"
29
+ upload(pupcap_prepare_script, remote_script_name)
30
+ run("chmod 0755 #{remote_script_name}")
31
+ force = pupcap_options[:force] ? "1" : "0"
32
+ sudo("env PUPCAP_FORCE=#{force} #{remote_script_name}")
33
+ run("rm #{remote_script_name}")
22
34
  end
23
35
  end
24
36
  end
@@ -0,0 +1,42 @@
1
+ set -e
2
+
3
+ test -e /root/.pupcap_prepare_ok -a ${PUPCAP_FORCE} = "0" && exit 0
4
+
5
+ if [ ! -e /root/.pupcap_prepare_locale_ok -o ${PUPCAP_FORCE} = "1" ]; then
6
+ locale-gen && update-locale LANG=en_US.UTF8 && touch /root/pupcap_prepare_locale_ok
7
+ fi
8
+
9
+ SOURCES_LIST=/etc/apt/sources.list
10
+
11
+ SOURCES_LIST_MD5=`md5sum ${SOURCES_LIST} | awk '{ print $1 }'`
12
+
13
+ if [ "$SOURCES_LIST_MD5" != "0af83b87b34bcdebf8a81a7ccc523e26" -o ${PUPCAP_FORCE} = "1" ]; then
14
+
15
+ cat <<EOF > ${SOURCES_LIST}
16
+ #############################################################
17
+ ################### OFFICIAL UBUNTU REPOS ###################
18
+ #############################################################
19
+
20
+ ###### Ubuntu Main Repos
21
+ deb mirror://mirrors.ubuntu.com/mirrors.txt precise main
22
+ deb-src mirror://mirrors.ubuntu.com/mirrors.txt precise main
23
+
24
+ ###### Ubuntu Update Repos
25
+ deb mirror://mirrors.ubuntu.com/mirrors.txt precise-security main
26
+ deb mirror://mirrors.ubuntu.com/mirrors.txt precise-updates main
27
+ deb-src mirror://mirrors.ubuntu.com/mirrors.txt precise-security main
28
+ deb-src mirror://mirrors.ubuntu.com/mirrors.txt precise-updates main
29
+ EOF
30
+ echo >> ${SOURCES_LIST} # new line
31
+
32
+ chown root:root ${SOURCES_LIST}
33
+ chmod 0644 ${SOURCES_LIST}
34
+ fi
35
+
36
+ apt-get -qy update > /dev/null
37
+ apt-get install -qy rsync wget rubygems vim git-core build-essential > /dev/null
38
+ apt-get -qy clean
39
+
40
+ /usr/bin/gem install -q --no-ri --no-rdoc --version '~> 2.7.1' puppet
41
+ touch /root/.pupcap_prepare_ok
42
+
@@ -0,0 +1,42 @@
1
+ require 'pupcap/action'
2
+ require 'pupcap/command'
3
+
4
+ class Pupcap::Action::Ssh < Pupcap::Action::Base
5
+ def initialize
6
+ check_role!
7
+ check_puppetfile!
8
+ ENV["ROLES"] = parsed_options[:role]
9
+ end
10
+
11
+ def start
12
+ cap = create_cap_for(parsed_options[:file])
13
+ cap_load_and_run_task(cap, "ssh")
14
+ end
15
+
16
+ def parsed_options
17
+ unless @parsed_options
18
+ options = default_options.dup
19
+ OptionParser.new do |opts|
20
+ opts.banner = "Usage: #{File.basename($0)} [options] <role> ssh"
21
+
22
+ opts.on("-f", "--file FILE", "A recipe file to load") do |file|
23
+ options[:file] = File.expand_path(file)
24
+ end
25
+
26
+ opts.on("-h", "--help", "Displays this help info") do
27
+ puts opts
28
+ exit 0
29
+ end
30
+ end.parse!
31
+ options[:role] = ARGV.first
32
+ @parsed_options = options
33
+ end
34
+ @parsed_options
35
+ end
36
+
37
+ def default_options
38
+ {
39
+ :file => File.expand_path("Puppetfile"),
40
+ }
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ namespace :ssh do
2
+ task :default do
3
+ server = find_servers_for_task(current_task).first
4
+ host = Pupcap::Command.server_host(self, server)
5
+ port = Pupcap::Command.server_port(self, server)
6
+ exec "ssh #{host} -t -p #{port} -i #{ssh_options[:keys]} '${SHELL} -l'"
7
+ end
8
+ end
9
+
data/lib/pupcap/cli.rb CHANGED
@@ -4,60 +4,21 @@ require 'pupcap'
4
4
  class Pupcap::CLI
5
5
  class << self
6
6
  def start
7
- get_action
8
- require "pupcap/action/#{options[:action]}"
9
- klass = Pupcap::Action.const_get(options[:action].capitalize)
10
- inst = klass.new(options[:file], options)
11
- inst.start
12
- end
13
-
14
- private
15
- def get_action
16
- options_parser
17
-
18
- action = ARGV[1]
19
- role = ARGV[0]
20
- if !action || !valid_actions.include?(action)
21
- $stderr.puts "Please specify a action to run: #{valid_actions.join("|")}"
22
- exit 1
23
- end
24
-
25
- if !role
26
- $stderr.puts "Please specify a role to run"
27
- exit 1
28
- end
29
-
30
- unless File.exists?(options[:file])
31
- $stderr.puts "A file #{options[:file]} does not exists"
32
- exit 1
33
- end
34
-
35
- options.merge!(:action => action, :role => role)
36
- end
37
-
38
- def valid_actions
39
- @valid_actions ||= %w{ prepare cook }
40
- end
41
-
42
- def options
43
- @options ||= {
44
- :file => File.expand_path("Puppetfile")
45
- }
7
+ action = ARGV.last
8
+ if !action || !valid_actions.include?(action)
9
+ $stderr.puts "Please specify a action to run: #{valid_actions.join("|")}"
10
+ exit 1
46
11
  end
47
12
 
48
- def options_parser
49
- @options_parser ||= OptionParser.new do |opts|
50
- opts.banner = "Usage: #{File.basename($0)} [options] role #{valid_actions.join("|")}"
51
-
52
- opts.on("-h", "--help", "Displays this help info") do
53
- puts opts
54
- exit 0
55
- end
13
+ ARGV.pop
14
+ require "pupcap/action/#{action}"
15
+ klass = Pupcap::Action.const_get(action.capitalize)
16
+ inst = klass.new
17
+ inst.start
18
+ end
56
19
 
57
- opts.on("-f", "--file FILE", "A recipe file to load") do |file|
58
- options[:file] = File.expand_path(file)
59
- end
60
- end.parse!
61
- end
20
+ def valid_actions
21
+ %w{ prepare cook ssh }
22
+ end
62
23
  end
63
24
  end
@@ -0,0 +1,23 @@
1
+ require 'pupcap'
2
+
3
+ class Pupcap::Command
4
+ class << self
5
+ def ensure_local_dir(dir, mode = "0755")
6
+ run_local("mkdir -p #{dir} && chmod #{mode} #{dir}")
7
+ end
8
+
9
+ def run_local(cmd)
10
+ system cmd
11
+ fail "#{cmd} fail" if $?.to_i != 0
12
+ end
13
+
14
+ def server_port(cap, server)
15
+ server.port || cap.ssh_options[:port] || 22
16
+ end
17
+
18
+ def server_host(cap, server)
19
+ u = server.user || cap.fetch(:user)
20
+ u ? "#{u}@#{server.host}" : server.host
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ class Pupcap::LsbRelease
2
+ def initialize(cap)
3
+ @cap = cap
4
+ end
5
+
6
+ def name
7
+ @name ||= get("i")
8
+ end
9
+
10
+ def codename
11
+ @release ||= get("c")
12
+ end
13
+
14
+ private
15
+ def get(code)
16
+ code = @cap.capture("lsb_release -#{code}")
17
+ code.split(":")[1].to_s.strip
18
+ end
19
+ end
@@ -5,7 +5,7 @@ module Pupcap
5
5
 
6
6
  MAJOR = 0
7
7
  MINOR = 0
8
- PATCH = 1
8
+ PATCH = 2
9
9
 
10
10
  def self.to_s
11
11
  "#{MAJOR}.#{MINOR}.#{PATCH}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pupcap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -46,8 +46,12 @@ files:
46
46
  - lib/pupcap/action/cook/Capfile
47
47
  - lib/pupcap/action/prepare.rb
48
48
  - lib/pupcap/action/prepare/Capfile
49
- - lib/pupcap/action/prepare/ubuntu/precise.rb
49
+ - lib/pupcap/action/prepare/ubuntu/precise.sh
50
+ - lib/pupcap/action/ssh.rb
51
+ - lib/pupcap/action/ssh/Capfile
50
52
  - lib/pupcap/cli.rb
53
+ - lib/pupcap/command.rb
54
+ - lib/pupcap/lsb_release.rb
51
55
  - lib/pupcap/version.rb
52
56
  - pupcap.gemspec
53
57
  homepage: http://github.com/dima-exe/pupcap
@@ -1,48 +0,0 @@
1
- namespace :prepare do
2
- namespace :ubuntu do
3
- task :precise do
4
- run("#{sudo} [ ! -f /root/.prepare_locale_ok ] && #{sudo} locale-gen && #{sudo} update-locale LANG=en_US.UTF8 && #{sudo} touch /root/.prepare_locale_ok || true")
5
-
6
- tmp_list = "/tmp/sources.list.#{Time.now.to_i}"
7
- sources_list = "/etc/apt/sources.list"
8
-
9
- dist_upgraded = false
10
- current_list = capture("md5sum #{sources_list}").split(" ")[0].to_s.strip
11
- if current_list != "1f722c129d80782e4fa323a6a70dee59"
12
- sudo("cp #{sources_list} #{sources_list}.back#{Time.now.to_i}")
13
- put(precise_sources_list, tmp_list)
14
- sudo("cp #{tmp_list} #{sources_list}")
15
- sudo("chown root:root #{sources_list}")
16
- sudo("chmod 0644 #{sources_list}")
17
- run("rm -f #{tmp_list}")
18
- sudo("apt-get -qy update > /dev/null")
19
- if ENV['upgrade']
20
- run("echo \"grub-pc hold\" | #{sudo} dpkg --set-selections")
21
- sudo("apt-get -qy upgrade")
22
- run("echo \"grub-pc install\" | #{sudo} dpkg --set-selections")
23
- dist_upgraded = true
24
- end
25
- end
26
-
27
- sudo("apt-get install -qy rsync wget rubygems vim git-core build-essential > /dev/null")
28
- sudo("/usr/bin/gem install -q --no-ri --no-rdoc --version '~> 2.7.1' puppet")
29
- sudo("reboot") if dist_upgraded
30
- end
31
- end
32
- end
33
-
34
- UBUNTU_PRECISE_SOURCES_LIST = <<-CODE
35
- #############################################################
36
- ################### OFFICIAL UBUNTU REPOS ###################
37
- #############################################################
38
-
39
- ###### Ubuntu Main Repos
40
- deb mirror://mirrors.ubuntu.com/mirrors.txt precise main
41
- deb-src mirror://mirrors.ubuntu.com/mirrors.txt precise main
42
-
43
- ###### Ubuntu Update Repos
44
- deb mirror://mirrors.ubuntu.com/mirrors.txt precise-security main
45
- deb mirror://mirrors.ubuntu.com/mirrors.txt precise-updates main
46
- deb-src mirror://mirrors.ubuntu.com/mirrors.txt precise-security main
47
- deb-src mirror://mirrors.ubuntu.com/mirrors.txt precise-updates main
48
- CODE