pupcap 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -8,5 +8,5 @@ gemspec
8
8
  # are merged here.
9
9
  #
10
10
  group :development do
11
- gem 'rake', '0.8.7'
11
+ gem 'rake'
12
12
  end
data/README CHANGED
@@ -1 +1,5 @@
1
- Integrate puppet and capistrano
1
+ Masterless puppet with capistrano
2
+ =================================
3
+
4
+ Under development
5
+
data/bin/pupcap CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift File.expand_path("../../lib", __FILE__)
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ #require 'pathname'
6
+ #$:.unshift Pathname.new(File.expand_path(__FILE__)).realpath.join("../../lib")
4
7
 
5
8
  require 'pupcap/cli'
6
9
 
@@ -10,46 +10,4 @@ class Pupcap::Action::Apply < Pupcap::Action::Base
10
10
  cap = create_cap_for(parsed_options[:file])
11
11
  cap_load_and_run_task(cap, "apply")
12
12
  end
13
-
14
- def parsed_options
15
- unless @parsed_options
16
- options = default_options.dup
17
- OptionParser.new do |opts|
18
- opts.banner = "Usage: #{File.basename($0)} apply [options] <tasks>"
19
-
20
- opts.on("-f", "--file FILE", "A recipe file to load") do |file|
21
- options[:file] = File.expand_path(file)
22
- end
23
-
24
- opts.on("-h", "--help", "Displays this help info") do
25
- puts opts
26
- exit 0
27
- end
28
-
29
- opts.on("-d", "--debug", "Debug output") do
30
- options[:debug] = true
31
- end
32
-
33
- opts.on("-n", "--noop", "Noop") do |file|
34
- options[:noop] = true
35
- end
36
-
37
- opts.on("-w", "--without-librarian-puppet", "Deploy without librarian-puppet") do
38
- options[:without_librarian_puppet] = true
39
- end
40
- end.parse!
41
- options[:tasks] = ARGV
42
- @parsed_options = options
43
- end
44
- @parsed_options
45
- end
46
-
47
- def default_options
48
- {
49
- :file => File.expand_path("Pupcapfile"),
50
- :debug => false,
51
- :noop => false,
52
- :without_librarian_puppet => false
53
- }
54
- end
55
13
  end
@@ -1,47 +1,68 @@
1
- require 'erb'
1
+ _cset(:pupcap_apply_cmd) { "/usr/local/bin/puppet apply" }
2
+ _cset(:pupcap_librarian_cache) { "#{shared_path}/cache" }
3
+ _cset(:pupcap_librarian_install) { "/usr/local/bin/librarian-puppet install" }
4
+ _cset(:pupcap_path) { "#{latest_release}" }
5
+ _cset(:pupcap_hiera_config) { "#{pupcap_path}/hiera.yaml" }
6
+ _cset(:environment, 'production')
2
7
 
3
8
  namespace :deploy do
4
9
  task :finalize_update do
5
- if !pupcap_options[:without_librarian_puppet]
6
- debug = pupcap_options[:debug] ? " --verbose" : ""
7
- run("ln -sf #{shared_path}/librarian-puppet-cache #{release_path}/puppet/.tmp")
8
- run("cd #{release_path}/puppet ; /usr/local/bin/librarian-puppet install #{debug} --destructive; true")
9
- end
10
- end
11
-
12
- task :restart do
13
10
  end
14
11
  end
15
12
 
16
13
  namespace :apply do
17
14
  task :default do
18
15
  try_create_dirs
19
- find_and_execute_task("deploy")
20
- find_and_execute_task("deploy:cleanup")
21
- puppet
16
+ find_and_execute_task("deploy:update_code")
17
+ find_and_execute_task("deploy:create_symlink")
18
+ prepare
19
+ apply
20
+ cleanup
22
21
  end
23
22
 
24
23
  task :try_create_dirs do
25
- run("mkdir -p #{deploy_to}/releases ; mkdir -p #{deploy_to}/shared/librarian-puppet-cache ; chmod 0700 #{deploy_to}")
24
+ run <<-EOF.compact
25
+ mkdir -p #{deploy_to}/releases ;
26
+ mkdir -p #{pupcap_librarian_cache} ;
27
+ chmod 0700 #{deploy_to} ;
28
+ mkdir -p #{shared_path}/confdir ;
29
+ EOF
26
30
  end
27
31
 
28
- task :puppet do
29
- remote_command = "#{deploy_to}/apply.sh"
32
+ task :prepare do
33
+ run <<-EOF.compact
34
+ test -d /etc/puppet || (#{sudo} mkdir -p /etc/puppet && #{sudo} chown root:puppet /ect/puppet) ;
35
+ test -f #{pupcap_hiera_config} && #{sudo} ln -nsf #{pupcap_hiera_config} /etc/puppet/hiera.yaml ;
36
+ #{sudo} rsync -as --delete #{pupcap_path}/hieradata/ /etc/puppet/hieradata/ ;
30
37
 
31
- puppet = "/usr/local/bin/puppet"
32
- modules = "--modulepath=#{current_path}/puppet/modules:#{current_path}/puppet/site-modules"
33
- nook = pupcap_options[:noop] ? " --noop" : ""
34
- debug = pupcap_options[:debug] ? " --debug --verbose" : ""
38
+ ln -sf #{pupcap_librarian_cache} #{pupcap_path}/.tmp ;
39
+ cd #{pupcap_path} && #{pupcap_librarian_install} #{ENV['DEBUG'] && '--verbose'} --destructive ;
40
+ true
41
+ EOF
42
+ end
35
43
 
36
- erb = ERB.new(File.read("#{pupcap_root}/action/apply/puppet.sh.erb"))
37
- rs = erb.result(binding)
44
+ task :apply do
45
+ modules = "--modulepath=#{pupcap_path}/modules:#{pupcap_path}/site-modules"
46
+ env = "--environment=#{environment}"
47
+ noop = ENV['NOOP'] ? " --noop" : ""
48
+ debug = ENV['DEBUG'] ? " --debug --verbose" : ""
49
+ config = "--confdir=/etc/puppet/"
38
50
 
39
- put(rs, remote_command)
40
- run("chmod +x #{remote_command}")
41
- sudo("#{remote_command} \"$CAPISTRANO:HOSTROLES$\"")
51
+ cmd =<<-EOF.gsub(/\n/, ' ').gsub(/ +/, ' ')
52
+ for role in $(echo $CAPISTRANO:HOSTROLES$ | tr "," "\n") ;
53
+ do
54
+ echo "*** For: ${role}:#{environment} ***" &&
55
+ #{sudo} #{pupcap_apply_cmd} #{noop}#{debug} #{config} #{env} #{modules} #{pupcap_path}/manifests/${role}.pp ||
56
+ true ;
57
+ done
58
+ EOF
59
+ run(cmd)
42
60
  end
43
61
 
44
62
  task :cleanup do
45
- run("rm -rf #{deploy_to}")
63
+ run <<-EOF.compact
64
+ #{sudo} rm -rf #{deploy_to}/releases ;
65
+ #{sudo} rm -rf /etc/puppet/hieradata/*
66
+ EOF
46
67
  end
47
68
  end
@@ -1,131 +1,37 @@
1
+ require 'thor'
2
+ require 'thor/actions'
3
+ require 'thor/group'
4
+
1
5
  require 'pupcap/action'
2
- require 'pupcap/command'
3
- require 'fileutils'
4
- require 'erb'
5
6
 
6
- class Pupcap::Action::Init < Pupcap::Action::Base
7
- def initialize
8
- end
7
+ class Pupcap::Action::Init < Thor::Group
9
8
 
10
- def start
11
- create_directories
12
- create_vagrantfile
13
- create_capfile
14
- create_pp
15
- librarian_puppet
16
- create_gitignore
17
- create_prepare_script
18
- end
9
+ include Thor::Actions
19
10
 
20
- def create_prepare_script
21
- out = "#{work_dir}/prepare.sh.erb"
22
- if !File.exists?(out) || force?
23
- FileUtils.copy("#{lib_root}/init/prepare.sh.erb", "#{work_dir}/prepare.sh.erb")
24
- puts "create prepare.sh.erb"
25
- else
26
- puts "skip prepare.sh.erb"
27
- end
28
- end
11
+ argument :dir, :type => :string, :desc => "The directory"
12
+ desc "Initializes in the DIR"
13
+ class_option :ip, :type => :string, :default => "192.168.44.10"
29
14
 
30
- def create_vagrantfile
31
- out = "#{work_dir}/Vagrantfile"
32
- if !File.exists?(out) || force?
33
- erb = ERB.new(File.read("#{lib_root}/init/Vagrantfile.erb"))
34
- rs = erb.result(binding)
35
- File.open(out, "w+"){ |io| io.write rs }
36
- puts "create Vagrantfile"
37
- else
38
- puts "skip #{out}"
39
- end
15
+ def create_pupcap_directories
16
+ directory("action/init", dir)
40
17
  end
41
18
 
42
- def create_capfile
43
- out = "#{work_dir}/Pupcapfile"
44
- if !File.exists?(out) || force?
45
- erb = ERB.new(File.read("#{lib_root}/init/Pupcapfile.erb"))
46
- rs = erb.result(binding)
47
- File.open(out, "w+"){ |io| io.write rs }
48
- puts "create Capfile"
49
- else
50
- puts "skip #{out}"
19
+ def initialize_librarian_puppet
20
+ inside(dir) do
21
+ run("librarian-puppet init")
51
22
  end
52
23
  end
53
24
 
54
- def create_pp
55
- out = "#{work_dir}/puppet/manifests/site.pp"
56
- if !File.exists?(out) || force?
57
- erb = ERB.new(File.read("#{lib_root}/init/site.pp.erb"))
58
- rs = erb.result(binding)
59
- File.open(out, "w+"){ |io| io.write rs }
60
- puts "create puppet/manifests/site.pp"
61
- else
62
- puts "skip #{out}"
25
+ def inject_into_giignore
26
+ inside(dir) do
27
+ append_to_file(".gitignore", ".vagrant\n", :verbose => false)
28
+ append_to_file(".gitignore", "*.swp\n", :verbose => false)
63
29
  end
64
30
  end
65
31
 
66
- def create_directories
67
- FileUtils.mkdir_p("#{work_dir}/puppet/modules")
68
- FileUtils.mkdir_p("#{work_dir}/puppet/site-modules")
69
- FileUtils.mkdir_p("#{work_dir}/puppet/manifests")
70
- system("touch #{work_dir}/puppet/manifests/.gitkeep")
71
- system("touch #{work_dir}/puppet/site-modules/.gitkeep")
72
- end
73
-
74
- def librarian_puppet
75
- Pupcap::Command.run_local("(cd #{work_dir}/puppet && librarian-puppet init)")
76
- end
77
-
78
- def create_gitignore
79
- if !File.exists?("#{work_dir}.gitignore")
80
- FileUtils.copy("#{lib_root}/init/gitignore", "#{work_dir}/.gitignore")
81
- puts "create .gitignore"
82
- else
83
- puts "skip .gitignore"
32
+ private
33
+ def ip
34
+ options["ip"]
84
35
  end
85
- end
86
36
 
87
- def work_dir
88
- parsed_options[:directory]
89
- end
90
-
91
- def ip
92
- parsed_options[:ip]
93
- end
94
-
95
- def force?
96
- parsed_options[:force]
97
- end
98
-
99
- def parsed_options
100
- unless @parsed_options
101
- options = default_options.dup
102
- OptionParser.new do |opts|
103
- opts.banner = "Usage: #{File.basename($0)} init [options] <directory>"
104
- opts.on("-h", "--help", "Displays this help info") do
105
- puts opts
106
- exit 0
107
- end
108
- opts.on("-i", "--ip IP", "Address for vagrant host, default 192.168.44.10") do |ip|
109
- options[:ip] = ip
110
- end
111
- opts.on("-f", "--force", "Always create a Vagrantfile and Puppetfile") do
112
- options[:force] = true
113
- end
114
- end.parse!
115
- options[:directory] = ARGV[0]
116
- unless options[:directory]
117
- $stderr.puts "You must specify a directory"
118
- exit 1
119
- end
120
- @parsed_options = options
121
- end
122
- @parsed_options
123
- end
124
-
125
- def default_options
126
- {
127
- :ip => "192.168.44.10",
128
- :force => false
129
- }
130
- end
131
37
  end
@@ -0,0 +1,8 @@
1
+ task :production do
2
+ role :site, 'example.com'
3
+ end
4
+
5
+ task :vagrant do
6
+ set :environment, "development"
7
+ role :site, "vagrant@<%= options[:ip] %>"
8
+ end
@@ -20,7 +20,7 @@ Vagrant::Config.run do |config|
20
20
  # via the IP. Host-only networks can talk to the host machine as well as
21
21
  # any other machines on the same network, but cannot be accessed (through this
22
22
  # network interface) by any external networks.
23
- config.vm.network :hostonly, "<%= ip %>"
23
+ config.vm.network :hostonly, "<%= options[:ip] %>"
24
24
 
25
25
  # Assign this VM to a bridged network, allowing you to connect directly to a
26
26
  # network using the host's network device. This makes the VM appear as another
@@ -0,0 +1,8 @@
1
+ ---
2
+ :hierarchy:
3
+ - %{environment}
4
+ - common
5
+ :backends:
6
+ - yaml
7
+ :yaml:
8
+ :datadir: '/etc/puppet/hieradata'
@@ -0,0 +1,2 @@
1
+ ---
2
+ example::key: "I am example key"
@@ -0,0 +1,2 @@
1
+ ---
2
+ example::key: "I am example development key"
File without changes
@@ -15,15 +15,6 @@ then
15
15
  locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8
16
16
  fi
17
17
 
18
- #
19
- # set hostname
20
- #
21
- if test -n "${PUPCAP_HOSTNAME}"
22
- then
23
- echo ${PUPCAP_HOSTNAME} > /etc/hostname
24
- cat /etc/hosts | grep ${PUPCAP_HOSTNAME} || echo "127.0.0.1 ${PUPCAP_HOSTNAME}" >> /etc/hosts && /usr/sbin/service hostname start
25
- fi
26
-
27
18
  #
28
19
  # update sources.list
29
20
  #
@@ -1,62 +1,40 @@
1
+ require 'thor'
2
+ require 'thor/actions'
3
+ require 'thor/group'
4
+
1
5
  require 'pupcap/action'
2
- require 'pupcap/command'
3
- require 'pupcap/lsb_release'
4
6
 
5
- class Pupcap::Action::Prepare < Pupcap::Action::Base
6
- def initialize
7
- check_puppetfile!
8
- check_prepare_script!
9
- end
7
+ class Pupcap::Action::Prepare < Thor::Group
8
+
9
+ include Thor::Actions
10
+
11
+ desc "Prepare host"
12
+ class_option :pupcapfile, :type => :string, :default => -> { File.expand_path("Capfile") }, :aliases => "-f"
10
13
 
11
- def start
12
- cap = create_cap_for(parsed_options[:file])
13
- #lsb = Pupcap::LsbRelease.new(cap)
14
- cap_load_and_run_task(cap, "prepare")
14
+ def create_pupcap_directories
15
+ directory("init", dir)
15
16
  end
16
17
 
17
- def check_prepare_script!
18
- unless File.exists?(parsed_options[:script])
19
- $stderr.puts "File #{parsed_options[:script]} does not exists"
20
- exit 1
18
+ def initialize_librarian_puppet
19
+ inside(dir) do
20
+ run("librarian-puppet init")
21
21
  end
22
22
  end
23
23
 
24
- def parsed_options
25
- unless @parsed_options
26
- options = default_options.dup
27
- OptionParser.new do |opts|
28
- opts.banner = "Usage: #{File.basename($0)} prepare [options] <tasks>"
29
-
30
- opts.on("-h", "--help", "Displays this help info") do
31
- puts opts
32
- exit 0
33
- end
34
-
35
- opts.on("-F", "--force", "Force prepare") do
36
- options[:force] = true
37
- end
38
-
39
- opts.on("-f", "--file FILE", "A recipe file to load") do |file|
40
- options[:file] = File.expand_path(file)
41
- end
42
-
43
- opts.on("-n", "--hostname NAME", "Set hostname") do |name|
44
- options[:hostname] = name
45
- end
46
- end.parse!
47
- options[:tasks] = ARGV
48
- @parsed_options = options
24
+ def inject_into_giignore
25
+ inside(dir) do
26
+ append_to_file(".gitignore", ".vagrant\n", :verbose => false)
27
+ append_to_file(".gitignore", "*.swp\n", :verbose => false)
49
28
  end
50
- @parsed_options
51
29
  end
52
30
 
53
- def default_options
54
- {
55
- :file => File.expand_path("Pupcapfile"),
56
- :script => File.expand_path("prepare.sh.erb"),
57
- :force => false,
58
- :upgrade => false
59
- }
31
+ def self.source_root
32
+ File.dirname(__FILE__)
60
33
  end
61
- end
62
34
 
35
+ private
36
+ def ip
37
+ options["ip"]
38
+ end
39
+
40
+ end
@@ -1,10 +1,9 @@
1
- require 'net/ssh/multi'
1
+ _cset(:pupcap_prepare_script, "/tmp/pupcap_prepare.sh")
2
2
 
3
3
  namespace :prepare do
4
4
  task :default do
5
- generate_keys
6
5
  try_ssh_copy_id
7
- run_script
6
+ script
8
7
  end
9
8
 
10
9
  task :try_ssh_copy_id do
@@ -18,35 +17,27 @@ namespace :prepare do
18
17
  end
19
18
 
20
19
  task :ssh_copy_id do
21
- remote_key_path = "/tmp/#{application}_id.pub.#{Time.now.to_i}"
22
- upload(provision_key_pub, remote_key_path)
23
- run("mkdir -p ~/.ssh && chmod 0700 ~/.ssh")
24
- run("cat #{remote_key_path} >> ~/.ssh/authorized_keys && chmod 0600 ~/.ssh/authorized_keys")
25
- run("rm -f #{remote_key_path}")
26
- end
20
+ key_content = File.read(provision_key_pub).strip
21
+ content = capture("test -d ~/.ssh && cat ~/.ssh/authorized_keys || echo")
27
22
 
28
- task :generate_keys do
29
- unless File.exists?(provision_key)
30
- logger.important("Generate keys")
31
- Pupcap::Command.ensure_local_dir("#{local_root}/.keys", "0700")
32
- Pupcap::Command.run_local("ssh-keygen -q -b 1024 -t rsa -C \"#{application} provision key\" -f #{provision_key}")
33
- Pupcap::Command.run_local("chmod 0600 #{provision_key}")
34
- Pupcap::Command.run_local("chmod 0600 #{provision_key_pub}")
23
+ unless content.include?(key_content)
24
+ remote_key_path = "/tmp/#{application}_id.pub.#{Time.now.to_i}"
25
+ put(key_content, remote_key_path)
26
+ run <<-EOF.compact
27
+ mkdir -p ~/.ssh && chmod 0700 ~/.ssh ;
28
+ cat #{remote_key_path} >> ~/.ssh/authorized_keys && chmod 0600 ~/.ssh/authorized_keys ;
29
+ rm -f #{remote_key_path}
30
+ EOF
35
31
  end
36
32
  end
37
33
 
38
- task :run_script do
34
+ task :script do
39
35
  template = pupcap_options[:script]
40
- prepare_script = ERB.new(File.read template).result(binding)
41
-
42
- set :use_sudo, true
36
+ content = ERB.new(File.read template).result(binding)
43
37
 
44
- remote_script_name = "/tmp/pupcap_prepare.sh"
45
- put(prepare_script, remote_script_name)
46
- run("chmod 0755 #{remote_script_name}")
47
- force = pupcap_options[:force] ? "1" : "0"
48
- hostname = pupcap_options[:hostname] ? " PUPCAP_HOSTNAME=#{pupcap_options[:hostname]}" : ""
49
- sudo("env PUPCAP_FORCE=#{force}#{hostname} #{remote_script_name}")
50
- run("rm #{remote_script_name}")
38
+ put(content, pupcap_prepare_script)
39
+ run("chmod 0700 #{pupcap_prepare_script}")
40
+ force = ENV['FORCE'] ? "1" : "0"
41
+ run("#{sudo} env PUPCAP_FORCE=#{force} #{pupcap_prepare_script}; rm -f #{pupcap_prepare_script}")
51
42
  end
52
43
  end
@@ -10,31 +10,4 @@ class Pupcap::Action::Ssh < Pupcap::Action::Base
10
10
  cap = create_cap_for(parsed_options[:file])
11
11
  cap_load_and_run_task(cap, "ssh")
12
12
  end
13
-
14
- def parsed_options
15
- unless @parsed_options
16
- options = default_options.dup
17
- OptionParser.new do |opts|
18
- opts.banner = "Usage: #{File.basename($0)} [options] ssh <role>"
19
-
20
- opts.on("-f", "--file FILE", "A recipe file to load") do |file|
21
- options[:file] = File.expand_path(file)
22
- end
23
-
24
- opts.on("-h", "--help", "Displays this help info") do
25
- puts opts
26
- exit 0
27
- end
28
- end.parse!
29
- options[:tasks] = ARGV
30
- @parsed_options = options
31
- end
32
- @parsed_options
33
- end
34
-
35
- def default_options
36
- {
37
- :file => File.expand_path("Pupcapfile"),
38
- }
39
- end
40
13
  end
@@ -2,9 +2,7 @@ namespace :ssh do
2
2
  task :default do
3
3
  server = find_servers_for_task(current_task).first
4
4
  if server
5
- host = Pupcap::Command.server_host(self, server)
6
- port = Pupcap::Command.server_port(self, server)
7
- exec "ssh #{host} -t -p #{port} -i #{ssh_options[:keys]} '${SHELL} -l'"
5
+ exec "ssh #{server} -A -t -i #{ssh_options[:keys]} '${SHELL} -l'"
8
6
  end
9
7
  end
10
8
  end
@@ -0,0 +1,39 @@
1
+ require 'pupcap'
2
+ require 'capistrano'
3
+ require 'capistrano/cli'
4
+
5
+ module Pupcap::Capistrano
6
+ def cap_execute_tasks(file, tasks)
7
+ cap = cap_create_instance
8
+ cap = yield(cap) if block_given?
9
+ ["deploy", pupcap_capfile, file].each{|f| cap.load f }
10
+ tasks.each do |task|
11
+ cap.find_and_execute_task(task)
12
+ end
13
+ cap
14
+ end
15
+
16
+ def cap_create_instance
17
+ cap = Capistrano::Configuration.new
18
+
19
+ cap.logger.level = Capistrano::Logger::DEBUG
20
+
21
+ cap.set :application, application
22
+ cap.set :pupcap_root, pupcap_root
23
+ cap.set :provision_key, provision_key
24
+ cap.set :provision_key_pub, provision_key_pub
25
+ cap.set :deploy_to, "/tmp/pupcap"
26
+ cap.set :use_sudo, false
27
+ cap.set :pupcap_options, options
28
+ cap.ssh_options[:keys] = cap.provision_key
29
+ cap.ssh_options[:forward_agent] = true
30
+ cap.default_run_options[:pty] = true
31
+
32
+ cap.set :repository, "."
33
+ cap.set :scm, :none
34
+ cap.set :deploy_via, :copy
35
+
36
+ cap.set :copy_exclude, [".git", ".keys"]
37
+ cap
38
+ end
39
+ end
data/lib/pupcap/cli.rb CHANGED
@@ -1,23 +1,93 @@
1
- require 'optparse'
1
+ require 'thor'
2
+ require 'thor/actions'
2
3
  require 'pupcap'
4
+ require 'pupcap/capistrano'
3
5
 
4
- class Pupcap::CLI
5
- class << self
6
- def start
7
- action = ARGV.shift
8
- if !action || !valid_actions.include?(action)
9
- $stderr.puts "Please specify a action to run: #{valid_actions.join("|")}"
10
- exit 1
11
- end
6
+ class Pupcap::CLI < Thor
7
+ include Thor::Actions
8
+ include Pupcap::Capistrano
12
9
 
13
- require "pupcap/action/#{action}"
14
- klass = Pupcap::Action.const_get(action.capitalize)
15
- inst = klass.new
16
- inst.start
10
+ desc "init DIR", "Initialize pupcap into DIR"
11
+ method_option :ip, :type => :string, :default => "192.168.44.11", :alias => "-i",
12
+ :desc => "Generate Vagrantfile with that ip address"
13
+ def init(dir)
14
+ directory("action/init", dir)
15
+ inside(dir) do
16
+ append_to_file(".gitignore", ".vagrant\n", :verbose => false)
17
+ append_to_file(".gitignore", "*.swp\n", :verbose => false)
18
+ run("librarian-puppet init")
17
19
  end
20
+ end
21
+
22
+ desc "prepare [TASKS]", "Prepare target host"
23
+ method_option :file, :type => :string, :default => File.expand_path("Capfile"),
24
+ :desc => "Capfile"
25
+ method_option :script, :type => :string, :default => File.expand_path("prepare.sh.erb"),
26
+ :desc => "The shell script who be execute in target host"
27
+ def prepare(*tasks)
28
+ error "#{options[:file]} does not exists" unless File.exists?(options[:file])
29
+ error "#{options[:script]} does not exists" unless File.exists?(options[:script])
18
30
 
19
- def valid_actions
20
- %w{ prepare apply ssh init noop }
31
+ unless File.exists?(provision_key)
32
+ inside pupcap_root do
33
+ empty_directory(".keys")
34
+ chmod(".keys", 0700)
35
+ run("ssh-keygen -q -b 1024 -t rsa -C \"#{application} provision key\" -f #{provision_key}")
36
+ chmod(provision_key, 0600)
37
+ chmod(provision_key_pub, 0600)
38
+ end
21
39
  end
40
+ cap_execute_tasks(capfile("prepare"), tasks << "prepare")
41
+ end
42
+
43
+ desc "apply [TASKS]", "Puppet apply"
44
+ method_option :file, :type => :string, :default => File.expand_path("Capfile"),
45
+ :desc => "Capfile"
46
+ def apply(*tasks)
47
+ cap_execute_tasks(capfile("apply"), tasks << "apply")
48
+ end
49
+
50
+ desc "noop [TASKS]", "Puppet noop"
51
+ method_option :file, :type => :string, :default => File.expand_path("Capfile"),
52
+ :desc => "Capfile"
53
+ def noop(*tasks)
54
+ ENV['NOOP'] = '1'
55
+ apply(*tasks)
56
+ end
57
+
58
+ desc "ssh [TASKS]", "Open remote console"
59
+ method_option :file, :type => :string, :default => File.expand_path("Capfile"),
60
+ :desc => "Capfile"
61
+ def ssh(*tasks)
62
+ cap_execute_tasks(capfile("ssh"), tasks << "ssh")
63
+ end
64
+
65
+ def self.source_root
66
+ File.dirname(__FILE__)
22
67
  end
68
+
69
+ private
70
+ def capfile(name)
71
+ self.class.source_root + "/action/#{name}/Capfile"
72
+ end
73
+
74
+ def pupcap_capfile
75
+ options[:file]
76
+ end
77
+
78
+ def pupcap_root
79
+ Pathname.new(File.dirname(pupcap_capfile))
80
+ end
81
+
82
+ def provision_key
83
+ pupcap_root.join(".keys/provision").to_s
84
+ end
85
+
86
+ def application
87
+ pupcap_root.basename.to_s
88
+ end
89
+
90
+ def provision_key_pub
91
+ "#{provision_key}.pub"
92
+ end
23
93
  end
@@ -1,11 +1,11 @@
1
1
  require 'scanf'
2
2
  module Pupcap
3
3
 
4
- class Version
4
+ class VERSION
5
5
 
6
6
  MAJOR = 0
7
- MINOR = 2
8
- PATCH = 3
7
+ MINOR = 3
8
+ PATCH = 0
9
9
 
10
10
  def self.to_s
11
11
  "#{MAJOR}.#{MINOR}.#{PATCH}"
data/pupcap.gemspec CHANGED
@@ -5,7 +5,7 @@ require "pupcap/version"
5
5
  Gem::Specification.new do |s|
6
6
 
7
7
  s.name = "pupcap"
8
- s.version = Pupcap::Version.to_s
8
+ s.version = Pupcap::VERSION.to_s
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.authors = ["Dmitry Galinsky"]
11
11
  s.email = ["dima.exe@gmail.com"]
@@ -17,23 +17,9 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
19
 
20
- if s.respond_to? :specification_version then
21
- s.specification_version = 3
22
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
23
- s.add_runtime_dependency(%q<capistrano>, [">= 2.12.0"])
24
- s.add_runtime_dependency(%q<vagrant>, [">= 1.0.0"])
25
- s.add_runtime_dependency(%q<librarian-puppet>, [">= 0.9.7"])
26
- s.add_runtime_dependency(%q<net-ssh-multi>, [">= 1.1.0"])
27
- else
28
- s.add_dependency(%q<capistrano>, [">= 2.12.0"])
29
- s.add_dependency(%q<vagrant>, [">= 1.0.0"])
30
- s.add_dependency(%q<librarian-puppet>, [">= 0.9.7"])
31
- s.add_dependency(%q<net-ssh-multi>, [">= 1.1.0"])
32
- end
33
- else
34
- s.add_dependency(%q<capistrano>, [">= 2.12.0"])
35
- s.add_dependency(%q<vagrant>, [">= 1.0.0"])
36
- s.add_dependency(%q<librarian-puppet>, [">= 0.9.7"])
37
- s.add_dependency(%q<net-ssh-multi>, [">= 1.1.0"])
38
- end
20
+ s.add_runtime_dependency("capistrano", [">= 2.12.0"])
21
+ s.add_runtime_dependency("vagrant", [">= 1.0.0"])
22
+ s.add_runtime_dependency("librarian-puppet", [">= 0.9.7"])
23
+ s.add_runtime_dependency("net-ssh-multi", [">= 1.1.0"])
24
+ s.add_runtime_dependency("thor", [">= 0"])
39
25
  end
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.2.3
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-20 00:00:00.000000000 Z
12
+ date: 2012-11-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: 1.1.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: thor
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
78
94
  description: under development description
79
95
  email:
80
96
  - dima.exe@gmail.com
@@ -89,23 +105,24 @@ files:
89
105
  - Rakefile
90
106
  - bin/pupcap
91
107
  - lib/pupcap.rb
92
- - lib/pupcap/action.rb
93
108
  - lib/pupcap/action/apply.rb
94
109
  - lib/pupcap/action/apply/Capfile
95
- - lib/pupcap/action/apply/puppet.sh.erb
96
110
  - lib/pupcap/action/init.rb
97
- - lib/pupcap/action/init/Pupcapfile.erb
98
- - lib/pupcap/action/init/Vagrantfile.erb
99
- - lib/pupcap/action/init/gitignore
111
+ - lib/pupcap/action/init/Capfile.tt
112
+ - lib/pupcap/action/init/Vagrantfile.tt
113
+ - lib/pupcap/action/init/hiera.yaml
114
+ - lib/pupcap/action/init/hieradata/common.yaml
115
+ - lib/pupcap/action/init/hieradata/development.yaml
116
+ - lib/pupcap/action/init/manifests/site.pp
117
+ - lib/pupcap/action/init/modules/.empty_directory
100
118
  - lib/pupcap/action/init/prepare.sh.erb
101
- - lib/pupcap/action/init/site.pp.erb
102
- - lib/pupcap/action/noop.rb
119
+ - lib/pupcap/action/init/site-modules/.empty_directory
103
120
  - lib/pupcap/action/prepare.rb
104
121
  - lib/pupcap/action/prepare/Capfile
105
122
  - lib/pupcap/action/ssh.rb
106
123
  - lib/pupcap/action/ssh/Capfile
124
+ - lib/pupcap/capistrano.rb
107
125
  - lib/pupcap/cli.rb
108
- - lib/pupcap/command.rb
109
126
  - lib/pupcap/lsb_release.rb
110
127
  - lib/pupcap/version.rb
111
128
  - pupcap.gemspec
data/lib/pupcap/action.rb DELETED
@@ -1,75 +0,0 @@
1
- require 'pupcap'
2
- require 'capistrano'
3
- require 'capistrano/cli'
4
-
5
- module Pupcap::Action
6
- class Base
7
-
8
- def parsed_options
9
- {}
10
- end
11
-
12
- def check_puppetfile!
13
- unless File.exists?(parsed_options[:file])
14
- $stderr.puts "File #{parsed_options[:file]} does not exists"
15
- exit 1
16
- end
17
- end
18
-
19
- def check_tasks!
20
- if parsed_options[:tasks].empty?
21
- $stderr.puts "Please specify tasks"
22
- exit 1
23
- end
24
- end
25
-
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
- parsed_options[:tasks].each do |task|
32
- cap.find_and_execute_task(task)
33
- end
34
- cap
35
- end
36
-
37
- def lib_root
38
- File.dirname(File.expand_path __FILE__) + "/action"
39
- end
40
-
41
- def cap_load_and_run_task(cap, task)
42
- cap.load "deploy"
43
- cap.load "#{lib_root}/#{task}/Capfile"
44
- cap.trigger(:load)
45
- cap.find_and_execute_task(task, :before => :start, :after => :finish)
46
- cap.trigger(:exit)
47
- end
48
-
49
- private
50
-
51
- def set_cap_vars!(cap, file)
52
- app = ENV['app'] || File.basename(File.dirname(file))
53
- cap.set :application, app
54
- cap.set :local_root, File.dirname(file)
55
- cap.set :pupcap_root, File.dirname(File.expand_path __FILE__)
56
- cap.set :provision_key, "#{cap.local_root}/.keys/provision"
57
- cap.set :provision_key_pub, "#{cap.local_root}/.keys/provision.pub"
58
- cap.set :deploy_to, "/tmp/pupcap"
59
- cap.set :pupcap_options, parsed_options
60
- cap.ssh_options[:keys] = cap.provision_key
61
- cap.ssh_options[:forward_agent] = true
62
- cap.default_run_options[:pty] = true
63
-
64
- cap.set :repository, "."
65
- cap.set :scm, :none
66
- cap.set :deploy_via, :copy
67
-
68
- cap.set :copy_exclude, [".git", ".keys"]
69
- cap.set :repository, "."
70
- cap.set :keep_releases, 2
71
- cap.set :use_sudo, false
72
- cap
73
- end
74
- end
75
- end
@@ -1,8 +0,0 @@
1
- set -e
2
-
3
- for role in $(echo "${1}" | tr "," "\n")
4
- do
5
- echo "*** Role: ${role} ***"
6
- <%= puppet %> apply <%= nook + debug %> --detailed-exitcodes <%= modules %> <%= current_path %>/puppet/manifests/${role}.pp || true
7
- done
8
-
@@ -1,5 +0,0 @@
1
- # set :password, "any random string"
2
-
3
- task :vagrant do
4
- role :site, "vagrant@<%= ip %>"
5
- end
@@ -1,2 +0,0 @@
1
- .vagrant
2
- *.swp
@@ -1,9 +0,0 @@
1
- require 'pupcap/action/apply'
2
-
3
- class Pupcap::Action::Noop < Pupcap::Action::Apply
4
- def start
5
- cap = create_cap_for(parsed_options[:file])
6
- cap.pupcap_options[:noop] = true
7
- cap_load_and_run_task(cap, "apply")
8
- end
9
- end
@@ -1,23 +0,0 @@
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