itamae 1.2.0 → 1.2.2

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
  SHA1:
3
- metadata.gz: 3c531f6aca9ae4e769d8f073077e47c722be40c5
4
- data.tar.gz: 35844bba50ca0705a464208a49e521ff0525da0b
3
+ metadata.gz: bee2953f7e53e6c977a24568b6f1ef50b2209f40
4
+ data.tar.gz: 2b8e4200cbcbf4f2106185355e240ba2c9798863
5
5
  SHA512:
6
- metadata.gz: 84bf522e5530b3b3f11901987098106e33f15674017d1d32eacbf6e2806b62036e7a4394c7c544e46cdfdcadac3082b2179e25f3c344890d2bbe7e805bde0fda
7
- data.tar.gz: 7588acd8fb22db71c6a261bc47e09233535a24a0de9db260522980b85962b67085ba5394e6b496438c1b53e4c35e86b1952ba95c6ab9edc7e83a7656e78c930a
6
+ metadata.gz: 73481813d9a2e6d6ed1033e787dc8e0392a6b47c1e68de5df4af6b43e76b6bd0a67e9095c826aa51b9cd74e62cbb08767f41210f55ddfa8e088996f58c339963
7
+ data.tar.gz: a1627a795d970cbfb2eba039bb13a5d33141c5209a1a75d967b549937e1db0bba7b03199e02f5758d0326be534d1758ee7673a4516e3f652c12a34742c2623a8
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Simple and lightweight configuration management tool inspired by Chef.
4
4
 
5
+ - [CHANGELOG](https://github.com/itamae-kitchen/itamae/blob/master/CHANGELOG.md)
6
+
5
7
  ## Concept
6
8
 
7
9
  - Chef-like DSL
data/Rakefile CHANGED
@@ -84,8 +84,6 @@ namespace :release do
84
84
  end
85
85
  system "git add #{version_file}"
86
86
  system "git commit -m 'Bump up version'"
87
-
88
- Rake::Task["release"].invoke
89
87
  end
90
88
  end
91
89
 
@@ -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.1"
21
+ spec.add_runtime_dependency "specinfra", [">= 2.24.1", "< 3.0.0"]
22
22
  spec.add_runtime_dependency "hashie"
23
23
  spec.add_runtime_dependency "ansi"
24
24
  spec.add_runtime_dependency "schash", "~> 0.1.0"
@@ -25,20 +25,17 @@ module Itamae
25
25
  CommandExecutionError = Class.new(StandardError)
26
26
 
27
27
  class << self
28
- def set_type(type, opts = {})
29
- @instance = self.const_get(type.capitalize).new(opts)
30
- end
31
-
32
- def instance
33
- unless @instance
34
- raise "Before calling Backend.instance, call Backend.set_type."
35
- end
36
-
37
- @instance
28
+ def create(type, opts = {})
29
+ self.const_get(type.capitalize).new(opts)
38
30
  end
39
31
  end
40
32
 
41
33
  class Base
34
+ def initialize(options)
35
+ @options = options
36
+ @backend = create_specinfra_backend
37
+ end
38
+
42
39
  def run_command(commands, options = {})
43
40
  options = {error: true}.merge(options)
44
41
 
@@ -62,7 +59,7 @@ module Itamae
62
59
 
63
60
  Logger.debug "Executing `#{command}`..."
64
61
 
65
- result = Specinfra::Runner.run_command(command)
62
+ result = @backend.run_command(command)
66
63
  exit_status = result.exit_status
67
64
 
68
65
  Logger.formatter.with_indent do
@@ -104,61 +101,100 @@ module Itamae
104
101
  end
105
102
 
106
103
  def get_command(*args)
107
- Specinfra.command.get(*args)
104
+ @backend.command.get(*args)
108
105
  end
109
106
 
110
107
  def send_file(*args)
111
- Specinfra::Runner.send_file(*args)
108
+ @backend.send_file(*args)
112
109
  end
113
110
 
114
111
  def send_directory(*args)
115
- Specinfra::Runner.send_directory(*args)
112
+ @backend.send_directory(*args)
113
+ end
114
+
115
+ def host_inventory
116
+ @backend.host_inventory
116
117
  end
117
118
 
118
119
  def finalize
119
120
  # pass
120
121
  end
122
+
123
+ private
124
+
125
+ def create_specinfra_backend
126
+ raise NotImplementedError
127
+ end
121
128
  end
122
129
 
123
130
  # TODO: Make Specinfra's backends instanciatable
124
131
  class Local < Base
125
- def initialize(options)
126
- Specinfra.configuration.backend = :exec
132
+ private
133
+ def create_specinfra_backend
134
+ Specinfra::Backend::Exec.new()
127
135
  end
128
136
  end
129
137
 
130
138
  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
139
+ private
140
+ def create_specinfra_backend
141
+ Specinfra::Backend::Ssh.new(
142
+ request_pty: true,
143
+ host: ssh_options[:host_name],
144
+ disable_sudo: ssh_options[:disable_sudo],
145
+ ssh_options: ssh_options,
146
+ )
147
+ end
148
+
149
+ def ssh_options
150
+ opts = {}
151
+
152
+ opts[:host_name] = @options[:host]
153
+ opts[:user] = @options[:user] || Etc.getlogin
154
+ opts[:keys] = [@options[:key]] if @options[:key]
155
+ opts[:port] = @options[:port] if @options[:port]
156
+ opts[:disable_sudo] = true unless @options[:sudo]
157
+
158
+ if @options[:vagrant]
159
+ config = Tempfile.new('', Dir.tmpdir)
160
+ hostname = opts[:host] || 'default'
161
+ `vagrant ssh-config #{hostname} > #{config.path}`
162
+ opts.merge!(Net::SSH::Config.for(hostname, [config.path]))
163
+ opts[:host] = opts.delete(:host_name)
164
+ end
165
+
166
+ if @options[:ask_password]
167
+ print "password: "
168
+ password = STDIN.noecho(&:gets).strip
169
+ print "\n"
170
+ opts.merge!(password: password)
171
+ end
136
172
 
137
- Specinfra.configuration.backend = :ssh
173
+ opts
138
174
  end
139
175
  end
140
176
 
141
177
  class Docker < Base
142
- def initialize(options)
178
+ private
179
+ def create_specinfra_backend
143
180
  begin
144
181
  require 'docker'
145
182
  rescue LoadError
146
183
  Logger.fatal "To use docker backend, please install 'docker-api' gem"
147
184
  end
148
185
 
149
- Specinfra.configuration.docker_image = options[:image]
150
- Specinfra.configuration.docker_container = options[:container]
151
-
152
186
  # TODO: Move to Specinfra?
153
- Excon.defaults[:ssl_verify_peer] = options[:tls_verify_peer]
154
-
155
- Specinfra.configuration.backend = :docker
156
-
187
+ Excon.defaults[:ssl_verify_peer] = @options[:tls_verify_peer]
157
188
  ::Docker.logger = Logger
189
+
190
+ Specinfra::Backend::Docker.new(
191
+ docker_image: @options[:image],
192
+ docker_container: @options[:container],
193
+ )
158
194
  end
159
195
 
160
196
  def finalize
161
- image = Specinfra.backend.commit_container
197
+ image = @backend.commit_container
162
198
  Logger.info "Image created: #{image.id}"
163
199
  end
164
200
  end
@@ -1,10 +1,2 @@
1
1
  # TODO: Send patches to Specinfra
2
2
 
3
- Specinfra::Command::Base::User.class_eval do
4
- class << self
5
- def update_home_directory(user, directory)
6
- # -m: Move the content of the user's home directory to the new location.
7
- "usermod -m -d #{escape(directory)} #{escape(user)}"
8
- end
9
- end
10
- end
@@ -7,6 +7,11 @@ module Itamae
7
7
  class Node < Hashie::Mash
8
8
  ValidationError = Class.new(StandardError)
9
9
 
10
+ def initialize(initial_hash, backend = nil)
11
+ super(initial_hash)
12
+ @backend = backend
13
+ end
14
+
10
15
  def reverse_merge(other_hash)
11
16
  Hashie::Mash.new(other_hash).merge(self)
12
17
  end
@@ -19,7 +24,7 @@ module Itamae
19
24
  val = super(key)
20
25
  if val.nil?
21
26
  begin
22
- val = host_inventory[key]
27
+ val = @backend.host_inventory[key]
23
28
  rescue NotImplementedError, NameError
24
29
  val = nil
25
30
  end
@@ -277,7 +277,7 @@ module Itamae
277
277
  end
278
278
 
279
279
  def backend
280
- Backend.instance
280
+ runner.backend
281
281
  end
282
282
 
283
283
  def runner
@@ -8,9 +8,8 @@ module Itamae
8
8
  def run(recipe_files, backend_type, options)
9
9
  Logger.info "Starting Itamae..."
10
10
 
11
- set_backend_from_options(backend_type, options)
12
-
13
- runner = self.new(node_from_options(options))
11
+ backend = Backend.create(backend_type, options)
12
+ runner = self.new(backend, options)
14
13
  runner.load_recipes(recipe_files)
15
14
 
16
15
  if dot_file = options[:dot]
@@ -23,81 +22,23 @@ module Itamae
23
22
 
24
23
  runner.run(dry_run: options[:dry_run])
25
24
  end
26
-
27
- private
28
- def node_from_options(options)
29
- hash = {}
30
-
31
- if options[:ohai]
32
- unless Backend.instance.run_command("which ohai", error: false).exit_status == 0
33
- # install Ohai
34
- Logger.info "Installing Chef package... (to use Ohai)"
35
- Backend.instance.run_command("curl -L https://www.opscode.com/chef/install.sh | bash")
36
- end
37
-
38
- Logger.info "Loading node data via ohai..."
39
- hash.merge!(JSON.parse(Backend.instance.run_command("ohai").stdout))
40
- end
41
-
42
- if options[:node_json]
43
- path = File.expand_path(options[:node_json])
44
- Logger.info "Loading node data from #{path}..."
45
- hash.merge!(JSON.load(open(path)))
46
- end
47
-
48
- if options[:node_yaml]
49
- path = File.expand_path(options[:node_yaml])
50
- Logger.info "Loading node data from #{path}..."
51
- hash.merge!(YAML.load(open(path)))
52
- end
53
-
54
- Node.new(hash)
55
- end
56
-
57
- def set_backend_from_options(type, options)
58
- opts = {}
59
-
60
- case type
61
- when :ssh
62
- opts[:host] = options[:host]
63
- opts[:user] = options[:user] || Etc.getlogin
64
- opts[:keys] = [options[:key]] if options[:key]
65
- opts[:port] = options[:port] if options[:port]
66
- opts[:disable_sudo] = true unless options[:sudo]
67
-
68
- if options[:vagrant]
69
- config = Tempfile.new('', Dir.tmpdir)
70
- hostname = opts[:host] || 'default'
71
- `vagrant ssh-config #{hostname} > #{config.path}`
72
- opts.merge!(Net::SSH::Config.for(hostname, [config.path]))
73
- opts[:host] = opts.delete(:host_name)
74
- end
75
-
76
- if options[:ask_password]
77
- print "password: "
78
- password = STDIN.noecho(&:gets).strip
79
- print "\n"
80
- opts.merge!(password: password)
81
- end
82
- when :docker
83
- opts = options
84
- end
85
-
86
- Backend.set_type(type, opts)
87
- end
88
25
  end
89
26
 
90
- attr_accessor :node
91
- attr_accessor :tmpdir
92
- attr_accessor :children
27
+ attr_reader :backend
28
+ attr_reader :node
29
+ attr_reader :tmpdir
30
+ attr_reader :children
31
+
32
+ def initialize(backend, options)
33
+ @backend = backend
34
+ @options = options
93
35
 
94
- def initialize(node)
95
- @node = node
36
+ @node = create_node
96
37
  @tmpdir = "/tmp/itamae_tmp"
97
38
  @children = RecipeChildren.new
98
39
 
99
- Backend.instance.run_command(["mkdir", "-p", @tmpdir])
100
- Backend.instance.run_command(["chmod", "777", @tmpdir])
40
+ @backend.run_command(["mkdir", "-p", @tmpdir])
41
+ @backend.run_command(["chmod", "777", @tmpdir])
101
42
  end
102
43
 
103
44
  def load_recipes(paths)
@@ -110,7 +51,37 @@ module Itamae
110
51
 
111
52
  def run(options)
112
53
  children.run(options)
113
- Backend.instance.finalize
54
+ @backend.finalize
55
+ end
56
+
57
+ private
58
+ def create_node
59
+ hash = {}
60
+
61
+ if @options[:ohai]
62
+ unless @backend.run_command("which ohai", error: false).exit_status == 0
63
+ # install Ohai
64
+ Logger.info "Installing Chef package... (to use Ohai)"
65
+ @backend.run_command("curl -L https://www.opscode.com/chef/install.sh | bash")
66
+ end
67
+
68
+ Logger.info "Loading node data via ohai..."
69
+ hash.merge!(JSON.parse(@backend.run_command("ohai").stdout))
70
+ end
71
+
72
+ if @options[:node_json]
73
+ path = File.expand_path(@options[:node_json])
74
+ Logger.info "Loading node data from #{path}..."
75
+ hash.merge!(JSON.load(open(path)))
76
+ end
77
+
78
+ if @options[:node_yaml]
79
+ path = File.expand_path(@options[:node_yaml])
80
+ Logger.info "Loading node data from #{path}..."
81
+ hash.merge!(YAML.load(open(path)))
82
+ end
83
+
84
+ Node.new(hash, @backend)
114
85
  end
115
86
  end
116
87
  end
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.2.2
@@ -2,10 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  module Itamae
4
4
  describe Node do
5
+ let(:backend) { nil }
5
6
  describe "#reverse_merge" do
6
7
  it "merges a hash but the method receiver's value will be preferred" do
7
- a = described_class.new(a: :b, c: :d)
8
- expected = described_class.new(a: :b, c: :d, e: :f)
8
+ a = described_class.new({a: :b, c: :d}, backend)
9
+ expected = described_class.new({a: :b, c: :d, e: :f}, backend)
9
10
  expect(a.reverse_merge(a: :c, e: :f)).to eq(expected)
10
11
  end
11
12
  end
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.2.0
4
+ version: 1.2.2
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-22 00:00:00.000000000 Z
11
+ date: 2015-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -30,14 +30,20 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 2.21.1
33
+ version: 2.24.1
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: 3.0.0
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - ">="
39
42
  - !ruby/object:Gem::Version
40
- version: 2.21.1
43
+ version: 2.24.1
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: 3.0.0
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: hashie
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -254,7 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
260
  version: '0'
255
261
  requirements: []
256
262
  rubyforge_project:
257
- rubygems_version: 2.2.2
263
+ rubygems_version: 2.4.5
258
264
  signing_key:
259
265
  specification_version: 4
260
266
  summary: Simple Configuration Management Tool