pero 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9fe7de2ca2e843f7c2af48b8b3804438aa9ba062145a456b1807b18c4405274
4
- data.tar.gz: 6d98fb48aa4038a36b48ec9c26b2747c92ad732dc48b1ce3f34f94c6b8f769e9
3
+ metadata.gz: d2cd510f50571a49f36a9d83b33b6ec102c2ec31dce18ee08223b96d9767a867
4
+ data.tar.gz: a576229ec962f9359956f787591b3c14b7d6a779fae2224d06181f4508adb573
5
5
  SHA512:
6
- metadata.gz: 2110591370d40c13810cedd3d770c03ec2229b1b8612b16e7ef96d69772f1739d9c2185cfe5c3ee51ad25ad368a7f104cdbf641d9e84dc306c6e0f5c3558ab10
7
- data.tar.gz: b0b79c02857c85fee733f69d18ab31acc7c48d1931e2bf29e738c3e8366adf70e9d30ca2cd59b13ed57b9e2fa3bc49306f9088da129e9ecf51d3e5bd6afc4461
6
+ metadata.gz: de370da8d84760e9c441630e123ecce5af27fb52af670b9edc16ba62b14b4bdc4b156b343c0ba8f764dc3203cfa3eb5b6ffc9a0d6b17efaa5982e31f68e42e22
7
+ data.tar.gz: 743fc365959f454d404d11faf1dda6d4c89242e2e4b054d137c5887befc7fb027c5c56345f6bfc164db4c19e8081d27563e8b19bdcd117d6e1a0ea070940da88
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pero (0.1.0)
4
+ pero (0.1.9)
5
5
  docker-api
6
6
  logger
7
7
  net-ssh
@@ -41,7 +41,7 @@ GEM
41
41
  rspec-support (~> 3.9.0)
42
42
  rspec-support (3.9.3)
43
43
  sfl (2.3)
44
- specinfra (2.82.18)
44
+ specinfra (2.82.19)
45
45
  net-scp
46
46
  net-ssh (>= 2.7)
47
47
  net-telnet (= 0.1.1)
data/Rakefile CHANGED
@@ -4,3 +4,8 @@ require "rspec/core/rake_task"
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+
8
+ task :build_docker do
9
+ puts `docker build -f ./misc/Dockerfile -t pyama/puppet:3.0.1 .`
10
+ puts `docker push pyama/puppet:3.0.1`
11
+ end
@@ -20,8 +20,9 @@ module Pero
20
20
  option :user, type: :string, aliases: ['-x'], desc: "ssh user"
21
21
  option :key, type: :string, aliases: ['-i'], desc: "ssh private key"
22
22
  option :port, type: :numeric, aliases: ['-p'], desc: "ssh port"
23
+ option "timeout", default: 10, type: :numeric, desc: "ssh connect timeout"
23
24
  option :ssh_config, type: :string, desc: "ssh config path"
24
- option :environment, type: :string, desc: "puppet environment"
25
+ option :environment, type: :string, desc: "puppet environment", default: "production"
25
26
  option :ask_password, type: :boolean, default: false, desc: "ask ssh or sudo password"
26
27
  option :vagrant, type: :boolean, default: false, desc: "use vagrarant"
27
28
  option :sudo, type: :boolean, default: true, desc: "use sudo"
@@ -30,23 +31,46 @@ module Pero
30
31
 
31
32
  desc "versions", "show support version"
32
33
  def versions
33
- Pero::Puppet::Redhat.show_versions
34
+ begin
35
+ Pero::Puppet::Redhat.show_versions
36
+ rescue => e
37
+ Pero.log.error e.inspect
38
+ end
34
39
  end
35
40
 
36
41
  desc "apply", "puppet apply"
37
42
  shared_options
38
- option "server-version", type: :string, default: "6.12.0"
43
+ option "server-version", type: :string
44
+ option "image-name", type: :string
39
45
  option :noop, aliases: '-n', default: false, type: :boolean
46
+ option :test, aliases: '-t', default: false, type: :boolean
40
47
  option :verbose, aliases: '-v', default: true, type: :boolean
41
48
  option :tags, default: nil, type: :array
49
+ option :volumes, default: nil, type: :array
42
50
  option "one-shot", default: false, type: :boolean, desc: "stop puppet server after run"
43
51
  def apply(name_regexp)
44
- nodes = Pero::History.search(name_regexp)
45
- return unless nodes
46
- Parallel.each(nodes, in_process: options["concurrent"]) do |n|
47
- opt = n["last_options"].merge(options)
48
- puppet = Pero::Puppet.new(opt["host"], opt)
49
- puppet.apply
52
+
53
+ if !options["image-name"] && !options["server-version"]
54
+ Pero.log.error "image-name or server-version are required"
55
+ return
56
+ end
57
+
58
+ begin
59
+ prepare
60
+ nodes = Pero::History.search(name_regexp)
61
+ return unless nodes
62
+ Parallel.each(nodes, in_process: options["concurrent"]) do |n|
63
+ opt = n["last_options"].merge(options)
64
+ if options["image-name"]
65
+ opt.delete("server-version")
66
+ else
67
+ opt.delete("image-name")
68
+ end
69
+ puppet = Pero::Puppet.new(opt["host"], opt)
70
+ puppet.apply
71
+ end
72
+ rescue => e
73
+ Pero.log.error e.inspect
50
74
  end
51
75
  end
52
76
 
@@ -55,10 +79,23 @@ module Pero
55
79
  option "agent-version", type: :string
56
80
  option "node-name", aliases: '-N', default: "", type: :string, desc: "json node name(default hostname)"
57
81
  def bootstrap(*hosts)
58
- Parallel.each(hosts, in_process: options["concurrent"]) do |host|
59
- next if host =~ /^-/
60
- puppet = Pero::Puppet.new(host, options)
61
- puppet.install
82
+ begin
83
+ Parallel.each(hosts, in_process: options["concurrent"]) do |host|
84
+ raise "unknown option #{host}" if host =~ /^-/
85
+ puppet = Pero::Puppet.new(host, options)
86
+
87
+ Pero.log.info "bootstrap pero #{host}"
88
+ puppet.install
89
+ end
90
+ rescue => e
91
+ Pero.log.error e.inspect
92
+ end
93
+ end
94
+
95
+ no_commands do
96
+ def prepare
97
+ `bundle insatll` if File.exists?("Gemfile")
98
+ `bundle exec librarian-puppet install` if File.exists?("Puppetfile")
62
99
  end
63
100
  end
64
101
  end
@@ -4,16 +4,22 @@ require "retryable"
4
4
  require 'net/https'
5
5
  module Pero
6
6
  class Docker
7
- attr_reader :server_version
8
- def initialize(version, environment)
7
+ attr_reader :server_version, :image_name, :volumes
8
+ def initialize(version, image_name, environment, volumes)
9
9
  @server_version = version
10
+ @image_name = image_name
10
11
  @environment = environment
12
+ @volumes = volumes
11
13
  end
12
14
 
13
15
  def build
14
16
  Pero.log.info "start build container"
15
17
  begin
16
- image = ::Docker::Image.build(docker_file)
18
+ image = if image_name
19
+ ::Docker::Image.create('fromImage' => image_name)
20
+ else
21
+ ::Docker::Image.build(docker_file)
22
+ end
17
23
  rescue => e
18
24
  Pero.log.debug docker_file
19
25
  Pero.log.error "failed build container #{e.inspect}"
@@ -24,15 +30,20 @@ module Pero
24
30
  end
25
31
 
26
32
  def container_name
27
- "pero-#{server_version}-#{Digest::MD5.hexdigest(Dir.pwd)[0..5]}-#{@environment}"
33
+ "pero-#{Digest::MD5.hexdigest(Dir.pwd)[0..5]}-#{@environment}"
28
34
  end
29
35
 
30
- def alerady_run?
36
+ def find
31
37
  ::Docker::Container.all(:all => true).find do |c|
32
- c.info["Names"].first == "/#{container_name}" && c.info["State"] != "exited"
38
+ c.info["Names"].first == "/#{container_name}"
33
39
  end
34
40
  end
35
41
 
42
+ def alerady_run?
43
+ c = find
44
+ c && c.info["State"] != "exited" && c
45
+ end
46
+
36
47
  def run
37
48
  ::Docker::Container.all(:all => true).each do |c|
38
49
  c.delete(:force => true) if c.info["Names"].first == "/#{container_name}"
@@ -45,42 +56,41 @@ module Pero
45
56
  'ExposedPorts' => { '8140/tcp' => {} },
46
57
  })
47
58
 
59
+ Pero.log.info "start puppet master container"
60
+ vols = volumes || []
61
+ vols << "#{Dir.pwd}:/etc/puppetlabs/code/environments/#{@environment}"
62
+ vols << "#{Dir.pwd}/keys:/etc/puppetlabs/puppet/eyaml/"
48
63
  container.start(
49
- 'Binds' => [
50
- "#{Dir.pwd}:/etc/puppetlabs/code/environments/#{@environment}",
51
- "#{Dir.pwd}/keys:/etc/puppetlabs/puppet/eyaml/",
52
- ],
64
+ 'Binds' => vols,
53
65
  'PortBindings' => {
54
66
  '8140/tcp' => [{ 'HostPort' => "0" }],
55
67
  },
56
- "AutoRemove" => true,
57
68
  )
58
69
 
59
- container = ::Docker::Container.all(:all => true).find do |c|
60
- c.info["Names"].first == "/#{container_name}"
61
- end
62
-
70
+ container = find
63
71
  raise "can't start container" unless container
64
-
65
72
  begin
66
73
  Retryable.retryable(tries: 20, sleep: 5) do
67
- https = Net::HTTP.new('localhost', container.info["Ports"].first["PublicPort"])
68
- https.use_ssl = true
69
- https.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
- Pero.log.debug "start server health check"
71
- https.start {
72
- response = https.get('/')
73
- Pero.log.debug "puppet http response #{response}"
74
- }
75
- rescue => e
76
- Pero.log.debug e.inspect
77
- raise e
74
+ begin
75
+ https = Net::HTTP.new('localhost', container.info["Ports"].first["PublicPort"])
76
+ https.use_ssl = true
77
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
78
+ Pero.log.debug "start server health check"
79
+ https.start {
80
+ response = https.get('/')
81
+ Pero.log.debug "puppet http response #{response}"
82
+ }
83
+ rescue => e
84
+ Pero.log.debug e.inspect
85
+ raise e
86
+ end
78
87
  end
79
88
  rescue
80
- container.kill
89
+ Pero.log.error "can't start container.please check [ docker logs #{container.info["id"]} ]"
90
+ container = find
91
+ container.kill if container && container.info["State"] != "exited"
81
92
  raise "can't start puppet server"
82
93
  end
83
-
84
94
  container
85
95
  end
86
96
 
@@ -125,7 +135,6 @@ CMD bash -c "rm -rf #{conf_dir}/ssl/* && #{create_ca} && #{run_cmd}"
125
135
 
126
136
  def create_ca
127
137
  release_package,package_name, conf_dir = if Gem::Version.new("5.0.0") > Gem::Version.new(server_version)
128
- #'(puppet cert generate `hostname` --dns_alt_names localhost,127.0.0.1 || puppet cert --allow-dns-alt-names sign `hostname`)'
129
138
  'puppet cert generate `hostname` --dns_alt_names localhost,127.0.0.1'
130
139
  elsif Gem::Version.new("6.0.0") > Gem::Version.new(server_version)
131
140
  'puppet cert generate `hostname` --dns_alt_names localhost,127.0.0.1'
@@ -27,6 +27,7 @@ module Pero
27
27
  options["node-name"]
28
28
  end
29
29
  options.delete("noop")
30
+ options.delete("tags")
30
31
  @h = {
31
32
  name: name,
32
33
  last_options: options
@@ -53,6 +53,7 @@ module Pero
53
53
  opts[:password] = @options["password"] if @options["password"]
54
54
  opts[:keys] = [@options["key"]] if @options["key"]
55
55
  opts[:port] = @options["port"] if @options["port"]
56
+ opts[:timeout] = @options["timeout"] if @options["timeout"]
56
57
 
57
58
  if @options["vagrant"]
58
59
  config = Tempfile.new('', Dir.tmpdir)
@@ -78,7 +79,6 @@ module Pero
78
79
  end
79
80
 
80
81
  def install
81
- Pero.log.info "bootstrap pero"
82
82
  osi = specinfra.os_info
83
83
  os = case osi[:family]
84
84
  when "redhat"
@@ -91,7 +91,6 @@ module Pero
91
91
  end
92
92
 
93
93
  def serve_master
94
- Pero.log.info "start puppet master container"
95
94
  container = run_container
96
95
  begin
97
96
  yield container
@@ -102,12 +101,14 @@ module Pero
102
101
  if @options["one-shot"]
103
102
  Pero.log.info "stop puppet master container"
104
103
  container.kill
104
+ else
105
+ Pero.log.info "puppet master container keep running"
105
106
  end
106
107
  end
107
108
  end
108
109
 
109
110
  def run_container
110
- docker = Pero::Docker.new(@options["server-version"], @options["environment"])
111
+ docker = Pero::Docker.new(@options["server-version"], @options["image-name"], @options["environment"], @options["volumes"])
111
112
  docker.alerady_run? || docker.run
112
113
  end
113
114
 
@@ -116,19 +117,19 @@ module Pero
116
117
  port = container.info["Ports"].first["PublicPort"]
117
118
  begin
118
119
  tmpdir=container.info["id"][0..5]
119
- Pero.log.info "start forwarding port:#{port}"
120
-
121
120
  in_ssh_forwarding(port) do |host, ssh|
122
121
  Pero.log.info "#{host}:puppet cmd[#{puppet_cmd}]"
123
122
  cmd = "mkdir -p /tmp/puppet/#{tmpdir} && unshare -m -- /bin/bash -c 'export PATH=$PATH:/opt/puppetlabs/bin/ && \
124
123
  mkdir -p `puppet config print ssldir` && mount --bind /tmp/puppet/#{tmpdir} `puppet config print ssldir` && \
125
124
  #{puppet_cmd}'"
126
125
  Pero.log.debug "run cmd:#{cmd}"
127
- ssh.exec!(specinfra.build_command(cmd)) do |channel, stream, data|
128
- Pero.log.info "#{host}:#{data.chomp}" if stream == :stdout && data.chomp != ""
129
- Pero.log.warn "#{host}:#{data.chomp}" if stream == :stderr && data.chomp != ""
130
- end
131
- ssh.exec!(specinfra.build_command("rm -rf /tmp/puppet/#{tmpdir}")) if @options["one-shot"]
126
+ ssh_exec(ssh, host, cmd)
127
+
128
+ if @options["one-shot"]
129
+ cmd = "/bin/rm -rf /tmp/puppet/#{tmpdir}"
130
+ ssh_exec(ssh, host, cmd)
131
+ end
132
+
132
133
  ssh.loop {true} if ENV['PERO_DEBUG']
133
134
  end
134
135
  rescue => e
@@ -139,17 +140,35 @@ module Pero
139
140
  Pero::History::Attribute.new(specinfra, @options).save
140
141
  end
141
142
 
143
+ def ssh_exec(ssh, host, cmd)
144
+ ssh.open_channel do |ch|
145
+ ch.request_pty
146
+ ch.on_data do |ch,data|
147
+ Pero.log.info "#{host}:#{data.chomp}"
148
+ end
149
+
150
+ ch.on_extended_data do |c,type,data|
151
+ Pero.log.error "#{host}:#{data.chomp}"
152
+ end
153
+
154
+ ch.exec specinfra.build_command(cmd) do |ch, success|
155
+ raise "could not execute #{cmd}" unless success
156
+ end
157
+ end
158
+ ssh.loop
159
+ end
160
+
142
161
  def puppet_cmd
143
162
  if Gem::Version.new("5.0.0") > Gem::Version.new(@options["agent-version"])
144
- "puppet agent --no-daemonize --onetime #{parse_puppet_option(@options)} --server localhost"
163
+ "puppet agent --no-daemonize --onetime #{parse_puppet_option(@options)} --ca_port 8140 --ca_server localhost --masterport 8140 --server localhost"
145
164
  else
146
- "/opt/puppetlabs/bin/puppet agent --no-daemonize --onetime #{parse_puppet_option(@options)} --server localhost"
165
+ "/opt/puppetlabs/bin/puppet agent --no-daemonize --onetime #{parse_puppet_option(@options)} --ca_server localhost --masterport 8140 --server localhost"
147
166
  end
148
167
  end
149
168
 
150
169
  def parse_puppet_option(options)
151
170
  ret = ""
152
- %w(noop verbose).each do |n|
171
+ %w(noop verbose test).each do |n|
153
172
  ret << " --#{n}" if options[n]
154
173
  end
155
174
  ret << " --tags #{options["tags"].join(",")}" if options["tags"]
@@ -163,6 +182,7 @@ module Pero
163
182
  options.delete(:strict_host_key_checking)
164
183
  end
165
184
 
185
+ Pero.log.info "start forwarding #{specinfra.get_config(:host)}:8140 => localhost:#{port}"
166
186
  Net::SSH.start(
167
187
  specinfra.get_config(:host),
168
188
  options[:user],
@@ -1,3 +1,3 @@
1
1
  module Pero
2
- VERSION = "0.1.5"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,11 @@
1
+ FROM centos:6
2
+ RUN yum -y install curl epel-release
3
+ RUN rpm -ivh https://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-12.noarch.rpm
4
+ RUN curl -O http://software.exogeni.net/repo/puppet/6/products/x86_64/puppet-server-3.0.1-1.el6.noarch.rpm && \
5
+ curl -O http://software.exogeni.net/repo/puppet/6/products/x86_64/puppet-3.0.1-1.el6.noarch.rpm && \
6
+ yum -y install puppet-3.0.1-1.el6.noarch.rpm puppet-server-3.0.1-1.el6.noarch.rpm
7
+ RUN mkdir -p /etc/puppetlabs/code/environments/production
8
+
9
+ RUN echo -e "[master]\nvardir= /var/puppet\nmanifestdir = /var/puppet/data/manifests\n templatedir = /var/puppet/data/templates\n modulepath = /var/puppet/data/modules:/var/puppet/data/roles:/var/puppet/data/vendor/modules\nlogdir = /var/log/puppet\n rundir = /var/run/puppet\n ssldir = /var/puppet/ssl\n" > /etc/puppet/puppet.conf
10
+
11
+ CMD bash -c "rm -rf /etc/puppet/ssl/* && puppet cert generate `hostname` --dns_alt_names localhost,127.0.0.1 && echo '*' > /etc/puppet/autosign.conf && puppet master --no-daemonize --verbose"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pero
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pyama86
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-25 00:00:00.000000000 Z
11
+ date: 2020-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -179,6 +179,7 @@ files:
179
179
  - lib/pero/puppet/redhat.rb
180
180
  - lib/pero/ssh_executable.rb
181
181
  - lib/pero/version.rb
182
+ - misc/Dockerfile
182
183
  - pero.gemspec
183
184
  homepage: https://github.com/pyama86/pero
184
185
  licenses: