pero 0.1.5 → 0.2.0

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.
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: