itamae 1.1.26 → 1.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 +4 -4
- data/CHANGELOG.md +28 -0
- data/itamae.gemspec +2 -1
- data/lib/itamae/backend.rb +110 -65
- data/lib/itamae/cli.rb +11 -0
- data/lib/itamae/ext/specinfra.rb +0 -1
- data/lib/itamae/runner.rb +4 -3
- data/lib/itamae/version.txt +1 -1
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c531f6aca9ae4e769d8f073077e47c722be40c5
|
4
|
+
data.tar.gz: 35844bba50ca0705a464208a49e521ff0525da0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84bf522e5530b3b3f11901987098106e33f15674017d1d32eacbf6e2806b62036e7a4394c7c544e46cdfdcadac3082b2179e25f3c344890d2bbe7e805bde0fda
|
7
|
+
data.tar.gz: 7588acd8fb22db71c6a261bc47e09233535a24a0de9db260522980b85962b67085ba5394e6b496438c1b53e4c35e86b1952ba95c6ab9edc7e83a7656e78c930a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
## v1.2.0
|
2
|
+
|
3
|
+
Feature
|
4
|
+
|
5
|
+
- Docker backend
|
6
|
+
- This backend builds a Docker image.
|
7
|
+
- Usage: `itamae docker --image baseimage recipe.rb`
|
8
|
+
- NOTE: This feature is experimental.
|
9
|
+
|
10
|
+
## v1.1.26
|
11
|
+
|
12
|
+
Bugfix
|
13
|
+
|
14
|
+
- Always outdent.
|
15
|
+
|
16
|
+
## v1.1.25
|
17
|
+
|
18
|
+
Improvements
|
19
|
+
|
20
|
+
- Make logging less verbose by default. (by @eagletmt)
|
21
|
+
- Change indent width from 3 to 2.
|
22
|
+
|
23
|
+
## v1.1.24
|
24
|
+
|
25
|
+
Bugfixes
|
26
|
+
|
27
|
+
- Make `node` accessible from define block.
|
28
|
+
|
1
29
|
## v1.1.23
|
2
30
|
|
3
31
|
Feature
|
data/itamae.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
20
|
spec.add_runtime_dependency "thor"
|
21
|
-
spec.add_runtime_dependency "specinfra", ">= 2.
|
21
|
+
spec.add_runtime_dependency "specinfra", ">= 2.21.1"
|
22
22
|
spec.add_runtime_dependency "hashie"
|
23
23
|
spec.add_runtime_dependency "ansi"
|
24
24
|
spec.add_runtime_dependency "schash", "~> 0.1.0"
|
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "rspec", "~> 3.0"
|
29
29
|
spec.add_development_dependency "serverspec", "~> 2.1"
|
30
30
|
spec.add_development_dependency "pry-byebug"
|
31
|
+
spec.add_development_dependency "docker-api", "~> 1.20"
|
31
32
|
end
|
data/lib/itamae/backend.rb
CHANGED
@@ -20,102 +20,147 @@ module Specinfra
|
|
20
20
|
end
|
21
21
|
|
22
22
|
module Itamae
|
23
|
-
|
23
|
+
module Backend
|
24
24
|
UnknownBackendTypeError = Class.new(StandardError)
|
25
25
|
CommandExecutionError = Class.new(StandardError)
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
case type
|
31
|
-
when :local
|
32
|
-
Specinfra.configuration.backend = :exec
|
33
|
-
when :ssh
|
34
|
-
Specinfra.configuration.request_pty = true
|
35
|
-
Specinfra.configuration.host = options.delete(:host)
|
36
|
-
Specinfra.configuration.disable_sudo = options.delete(:disable_sudo)
|
37
|
-
Specinfra.configuration.ssh_options = options
|
38
|
-
|
39
|
-
Specinfra.configuration.backend = :ssh
|
40
|
-
else
|
41
|
-
raise UnknownBackendTypeError, "'#{type}' backend is unknown."
|
27
|
+
class << self
|
28
|
+
def set_type(type, opts = {})
|
29
|
+
@instance = self.const_get(type.capitalize).new(opts)
|
42
30
|
end
|
43
|
-
end
|
44
31
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
command = commands.map do |cmd|
|
50
|
-
Shellwords.escape(cmd)
|
51
|
-
end.join(' ')
|
52
|
-
else
|
53
|
-
command = commands
|
54
|
-
end
|
32
|
+
def instance
|
33
|
+
unless @instance
|
34
|
+
raise "Before calling Backend.instance, call Backend.set_type."
|
35
|
+
end
|
55
36
|
|
56
|
-
|
57
|
-
if cwd
|
58
|
-
command = "cd #{Shellwords.escape(cwd)} && #{command}"
|
37
|
+
@instance
|
59
38
|
end
|
39
|
+
end
|
60
40
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
41
|
+
class Base
|
42
|
+
def run_command(commands, options = {})
|
43
|
+
options = {error: true}.merge(options)
|
65
44
|
|
66
|
-
|
45
|
+
if commands.is_a?(Array)
|
46
|
+
command = commands.map do |cmd|
|
47
|
+
Shellwords.escape(cmd)
|
48
|
+
end.join(' ')
|
49
|
+
else
|
50
|
+
command = commands
|
51
|
+
end
|
67
52
|
|
68
|
-
|
69
|
-
|
53
|
+
cwd = options[:cwd]
|
54
|
+
if cwd
|
55
|
+
command = "cd #{Shellwords.escape(cwd)} && #{command}"
|
56
|
+
end
|
70
57
|
|
71
|
-
|
72
|
-
if
|
73
|
-
|
74
|
-
message = "exited with #{exit_status}"
|
75
|
-
else
|
76
|
-
method = :error
|
77
|
-
message = "Command `#{command}` failed. (exit status: #{exit_status})"
|
58
|
+
user = options[:user]
|
59
|
+
if user
|
60
|
+
command = "sudo -u #{Shellwords.escape(user)} -- /bin/sh -c #{Shellwords.escape(command)}"
|
78
61
|
end
|
79
62
|
|
80
|
-
Logger.
|
63
|
+
Logger.debug "Executing `#{command}`..."
|
81
64
|
|
82
|
-
|
83
|
-
|
65
|
+
result = Specinfra::Runner.run_command(command)
|
66
|
+
exit_status = result.exit_status
|
84
67
|
|
85
|
-
|
86
|
-
|
87
|
-
|
68
|
+
Logger.formatter.with_indent do
|
69
|
+
if exit_status == 0 || !options[:error]
|
70
|
+
method = :debug
|
71
|
+
message = "exited with #{exit_status}"
|
72
|
+
else
|
73
|
+
method = :error
|
74
|
+
message = "Command `#{command}` failed. (exit status: #{exit_status})"
|
88
75
|
end
|
89
76
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
77
|
+
Logger.public_send(method, message)
|
78
|
+
|
79
|
+
{"stdout" => result.stdout, "stderr" => result.stderr}.each_pair do |name, value|
|
80
|
+
next unless value && value != ''
|
81
|
+
|
82
|
+
if value.bytesize > 1024 * 1024
|
83
|
+
Logger.public_send(method, "#{name} is suppressed because it's too large")
|
84
|
+
next
|
95
85
|
end
|
96
86
|
|
97
|
-
|
87
|
+
value.each_line do |line|
|
88
|
+
# remove control chars
|
89
|
+
case line.encoding
|
90
|
+
when Encoding::UTF_8
|
91
|
+
line = line.tr("\u0000-\u001f\u007f\u2028",'')
|
92
|
+
end
|
93
|
+
|
94
|
+
Logger.public_send(method, "#{name} | #{line}")
|
95
|
+
end
|
98
96
|
end
|
99
97
|
end
|
98
|
+
|
99
|
+
if options[:error] && exit_status != 0
|
100
|
+
raise CommandExecutionError
|
101
|
+
end
|
102
|
+
|
103
|
+
result
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_command(*args)
|
107
|
+
Specinfra.command.get(*args)
|
100
108
|
end
|
101
109
|
|
102
|
-
|
103
|
-
|
110
|
+
def send_file(*args)
|
111
|
+
Specinfra::Runner.send_file(*args)
|
104
112
|
end
|
105
113
|
|
106
|
-
|
114
|
+
def send_directory(*args)
|
115
|
+
Specinfra::Runner.send_directory(*args)
|
116
|
+
end
|
117
|
+
|
118
|
+
def finalize
|
119
|
+
# pass
|
120
|
+
end
|
107
121
|
end
|
108
122
|
|
109
|
-
|
110
|
-
|
123
|
+
# TODO: Make Specinfra's backends instanciatable
|
124
|
+
class Local < Base
|
125
|
+
def initialize(options)
|
126
|
+
Specinfra.configuration.backend = :exec
|
127
|
+
end
|
111
128
|
end
|
112
129
|
|
113
|
-
|
114
|
-
|
130
|
+
class Ssh < Base
|
131
|
+
def initialize(options)
|
132
|
+
Specinfra.configuration.request_pty = true
|
133
|
+
Specinfra.configuration.host = options.delete(:host)
|
134
|
+
Specinfra.configuration.disable_sudo = options.delete(:disable_sudo)
|
135
|
+
Specinfra.configuration.ssh_options = options
|
136
|
+
|
137
|
+
Specinfra.configuration.backend = :ssh
|
138
|
+
end
|
115
139
|
end
|
116
140
|
|
117
|
-
|
118
|
-
|
141
|
+
class Docker < Base
|
142
|
+
def initialize(options)
|
143
|
+
begin
|
144
|
+
require 'docker'
|
145
|
+
rescue LoadError
|
146
|
+
Logger.fatal "To use docker backend, please install 'docker-api' gem"
|
147
|
+
end
|
148
|
+
|
149
|
+
Specinfra.configuration.docker_image = options[:image]
|
150
|
+
Specinfra.configuration.docker_container = options[:container]
|
151
|
+
|
152
|
+
# TODO: Move to Specinfra?
|
153
|
+
Excon.defaults[:ssl_verify_peer] = options[:tls_verify_peer]
|
154
|
+
|
155
|
+
Specinfra.configuration.backend = :docker
|
156
|
+
|
157
|
+
::Docker.logger = Logger
|
158
|
+
end
|
159
|
+
|
160
|
+
def finalize
|
161
|
+
image = Specinfra.backend.commit_container
|
162
|
+
Logger.info "Image created: #{image.id}"
|
163
|
+
end
|
119
164
|
end
|
120
165
|
end
|
121
166
|
end
|
data/lib/itamae/cli.rb
CHANGED
@@ -53,6 +53,17 @@ module Itamae
|
|
53
53
|
Runner.run(recipe_files, :ssh, options)
|
54
54
|
end
|
55
55
|
|
56
|
+
desc "docker RECIPE [RECIPE...]", "Create Docker image"
|
57
|
+
option :image, type: :string, required: true
|
58
|
+
option :tls_verify_peer, type: :boolean, default: true
|
59
|
+
def docker(*recipe_files)
|
60
|
+
if recipe_files.empty?
|
61
|
+
raise "Please specify recipe files."
|
62
|
+
end
|
63
|
+
|
64
|
+
Runner.run(recipe_files, :docker, options)
|
65
|
+
end
|
66
|
+
|
56
67
|
desc "version", "Print version"
|
57
68
|
def version
|
58
69
|
puts "Itamae v#{Itamae::VERSION}"
|
data/lib/itamae/ext/specinfra.rb
CHANGED
data/lib/itamae/runner.rb
CHANGED
@@ -58,8 +58,6 @@ module Itamae
|
|
58
58
|
opts = {}
|
59
59
|
|
60
60
|
case type
|
61
|
-
when :local
|
62
|
-
# do nothing
|
63
61
|
when :ssh
|
64
62
|
opts[:host] = options[:host]
|
65
63
|
opts[:user] = options[:user] || Etc.getlogin
|
@@ -81,9 +79,11 @@ module Itamae
|
|
81
79
|
print "\n"
|
82
80
|
opts.merge!(password: password)
|
83
81
|
end
|
82
|
+
when :docker
|
83
|
+
opts = options
|
84
84
|
end
|
85
85
|
|
86
|
-
Backend.
|
86
|
+
Backend.set_type(type, opts)
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -110,6 +110,7 @@ module Itamae
|
|
110
110
|
|
111
111
|
def run(options)
|
112
112
|
children.run(options)
|
113
|
+
Backend.instance.finalize
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
data/lib/itamae/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: itamae
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Arai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.21.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
40
|
+
version: 2.21.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: hashie
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: docker-api
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1.20'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.20'
|
153
167
|
description:
|
154
168
|
email:
|
155
169
|
- ryota.arai@gmail.com
|
@@ -240,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
240
254
|
version: '0'
|
241
255
|
requirements: []
|
242
256
|
rubyforge_project:
|
243
|
-
rubygems_version: 2.
|
257
|
+
rubygems_version: 2.2.2
|
244
258
|
signing_key:
|
245
259
|
specification_version: 4
|
246
260
|
summary: Simple Configuration Management Tool
|