itamae 1.1.26 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|