itamae 1.10.2 → 1.10.3

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: d537d0b8fccaf05648269fd73bf4b66418997561130cc32daeec44c731d7bc06
4
- data.tar.gz: ffb4e8c884f3a9fd62ddefd10ed8ef743928edb39fccbe0a3b95399d9ab40f7e
3
+ metadata.gz: 942ff87322e63633982fa6f7720817a6ea7b5752e5d98f6ab2430e081f096424
4
+ data.tar.gz: 4c8cef5f50960239692a9e5a5002f1bc79dbe958a7ac2f3e2cd15f414b410def
5
5
  SHA512:
6
- metadata.gz: 840de2dcfe70cf2100b09686ada740b61fa116189f1d9eda7fe5ed99b9b0e134bc60c83ffbc2034eefec475eba9c5f0e3f074048c75c6e0467f5d3f159260b56
7
- data.tar.gz: f0bc01b74bd79244bdf7f5b3f93c07ada68333a6427fcac4b1bfbbb3fed48b11b89ccc24a291c7e30665e33f86a0491f2b317e2bedd575780252b808f3e4af36
6
+ metadata.gz: '0391d1154a6e21eaaad3d9e96a494fc18a3f55b7e26254f28da43632be101e5128c08ccc54e4aa5adccf2f5723754cf810bb235890215498c9c1b959b3d28924'
7
+ data.tar.gz: 4135bdda547710499879432c71ad02d549f1e9cdf6c16be89ab97592c59dfd334c8830b93ddbeaa50d4dc400842f03874d643795f6cb349f0f3cb30249e90dfb
data/.travis.yml CHANGED
@@ -1,29 +1,21 @@
1
1
  language: ruby
2
2
  sudo: required
3
+ dist: xenial
3
4
  services:
4
5
  - docker
5
6
  rvm:
6
7
  - 2.3
7
8
  - 2.4
8
9
  - 2.5
10
+ - 2.6
9
11
  - ruby-head
10
12
  bundler_args: "--jobs=4 --retry=3"
11
13
  cache:
12
14
  bundler: true
13
- directories:
14
- - $HOME/docker
15
-
16
- before_cache:
17
- # Save tagged docker images
18
- - >
19
- mkdir -p $HOME/docker && docker images -a --filter='dangling=false' --format '{{.Repository}}:{{.Tag}} {{.ID}}'
20
- | xargs -n 2 -t sh -c 'test -e $HOME/docker/$1.tar.gz || docker save $0 | gzip -2 > $HOME/docker/$1.tar.gz'
21
15
 
22
16
  before_install:
23
- - gem update --system --no-document
24
- - gem install bundler --no-document
25
- # Load cached docker images
26
- - if [[ -d $HOME/docker ]]; then ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load"; fi
17
+ - travis_retry gem update --system || travis_retry gem update --system 2.7.8
18
+ - travis_retry gem install bundler --no-document || travis_retry gem install bundler --no-document -v 1.17.3
27
19
 
28
20
  script:
29
21
  - bundle exec rake spec
@@ -34,6 +26,11 @@ notifications:
34
26
  matrix:
35
27
  allow_failures:
36
28
  - rvm: ruby-head
29
+ include:
30
+ - rvm: 2.6
31
+ env: RUBYOPT="--jit"
32
+ - rvm: ruby-head
33
+ env: RUBYOPT="--jit"
37
34
  branches:
38
35
  only:
39
36
  - master
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## Unreleased
2
- [full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.10.2...master)
2
+ [full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.10.3...master)
3
+
4
+ ## v1.10.3
5
+ [full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.10.2...v1.10.3)
6
+
7
+ Bugfixes
8
+
9
+ - [Make `send_file` aware of `user` option](https://github.com/itamae-kitchen/itamae/pull/277)
3
10
 
4
11
  ## v1.10.2
5
12
  [full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.10.1...v1.10.2)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # [![](https://raw.githubusercontent.com/itamae-kitchen/itamae-logos/master/small/FA-Itamae-horizontal-01-180x72.png)](https://github.com/itamae-kitchen/itamae)
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/itamae.svg)](http://badge.fury.io/rb/itamae) [![Code Climate](https://codeclimate.com/github/ryotarai/itamae/badges/gpa.svg)](https://codeclimate.com/github/ryotarai/itamae) [![Build Status](https://travis-ci.org/itamae-kitchen/itamae.svg?branch=master)](https://travis-ci.org/itamae-kitchen/itamae) [![Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://itamae-slackin.herokuapp.com/)
3
+ [![Gem Version](https://badge.fury.io/rb/itamae.svg)](http://badge.fury.io/rb/itamae) [![Code Climate](https://codeclimate.com/github/ryotarai/itamae/badges/gpa.svg)](https://codeclimate.com/github/ryotarai/itamae) [![Build Status](https://travis-ci.org/itamae-kitchen/itamae.svg?branch=master)](https://travis-ci.org/itamae-kitchen/itamae) [![Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://join.slack.com/t/itamae/shared_invite/enQtNTExNTI3ODM1NTY5LTM5MWJlZTgwODE0YTUwMThiNzZjN2I1MGNlZjE2NjlmNzg5NTNlOTliMDhkNDNmNTQ2ZTgwMzZjNjI5NDJiZGI)
4
4
 
5
5
  Simple and lightweight configuration management tool inspired by Chef.
6
6
 
@@ -77,7 +77,7 @@ $ bundle exec rake spec
77
77
 
78
78
  ## Get Involved
79
79
 
80
- - [Join Slack team](https://itamae-slackin.herokuapp.com/)
80
+ - [Join Slack team](https://join.slack.com/t/itamae/shared_invite/enQtNTExNTI3ODM1NTY5LTM5MWJlZTgwODE0YTUwMThiNzZjN2I1MGNlZjE2NjlmNzg5NTNlOTliMDhkNDNmNTQ2ZTgwMzZjNjI5NDJiZGI)
81
81
 
82
82
  ## Presentations / Articles
83
83
 
data/Rakefile CHANGED
@@ -3,6 +3,10 @@ require 'rspec/core/rake_task'
3
3
  require 'tempfile'
4
4
  require 'net/ssh'
5
5
 
6
+ Dir['tasks/*.rb'].each do |file|
7
+ require_relative file
8
+ end
9
+
6
10
  desc 'Run unit and integration specs.'
7
11
  task :spec => ['spec:unit', 'spec:integration:all']
8
12
 
@@ -14,17 +18,18 @@ namespace :spec do
14
18
 
15
19
  namespace :integration do
16
20
  targets = ["ubuntu:trusty"]
21
+ container_name = 'itamae'
17
22
 
18
- task :all => targets
23
+ task :all => targets + ['spec:integration:local']
19
24
 
20
25
  targets.each do |target|
21
26
  desc "Run provision and specs to #{target}"
22
- task target => ["docker:#{target}", "provision:#{target}", "serverspec:#{target}"]
27
+ task target => ["docker:#{target}", "provision:#{target}", "serverspec:#{target}", 'clean_docker_container']
23
28
 
24
29
  namespace :docker do
25
30
  desc "Run docker for #{target}"
26
31
  task target do
27
- sh "docker run --privileged -d --name itamae #{target} /sbin/init"
32
+ sh "docker run --privileged -d --name #{container_name} #{target} /sbin/init"
28
33
  end
29
34
  end
30
35
 
@@ -36,6 +41,7 @@ namespace :spec do
36
41
  "spec/integration/recipes/default.rb",
37
42
  "spec/integration/recipes/default2.rb",
38
43
  "spec/integration/recipes/redefine.rb",
44
+ "spec/integration/recipes/docker.rb",
39
45
  ],
40
46
  [
41
47
  "--dry-run",
@@ -43,10 +49,10 @@ namespace :spec do
43
49
  ],
44
50
  ]
45
51
  suites.each do |suite|
46
- cmd = %w!bundle exec bin/itamae docker!
52
+ cmd = %w!bundle exec ruby -w bin/itamae docker!
47
53
  cmd << "-l" << (ENV['LOG_LEVEL'] || 'debug')
48
54
  cmd << "-j" << "spec/integration/recipes/node.json"
49
- cmd << "--container" << "itamae"
55
+ cmd << "--container" << container_name
50
56
  cmd << "--tag" << "itamae:latest"
51
57
  cmd += suite
52
58
 
@@ -61,11 +67,16 @@ namespace :spec do
61
67
  namespace :serverspec do
62
68
  desc "Run serverspec tests to #{target}"
63
69
  RSpec::Core::RakeTask.new(target.to_sym) do |t|
64
- ENV['DOCKER_CONTAINER'] = "itamae"
70
+ ENV['DOCKER_CONTAINER'] = container_name
65
71
  t.ruby_opts = '-I ./spec/integration'
66
- t.pattern = "spec/integration/*_spec.rb"
72
+ t.pattern = "spec/integration/[default|docker]_spec.rb"
67
73
  end
68
74
  end
75
+
76
+ desc 'Clean a docker container for test'
77
+ task :clean_docker_container do
78
+ sh('docker', 'rm', '-f', container_name)
79
+ end
69
80
  end
70
81
  end
71
82
  end
data/itamae.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_runtime_dependency "ansi"
33
33
  spec.add_runtime_dependency "schash", "~> 0.1.0"
34
34
 
35
- spec.add_development_dependency "bundler", "~> 1.3"
35
+ spec.add_development_dependency "bundler", ">= 1.3"
36
36
  spec.add_development_dependency "rake"
37
37
  spec.add_development_dependency "rspec", "~> 3.0"
38
38
  spec.add_development_dependency "serverspec", "~> 2.1"
data/lib/itamae.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "itamae/version"
2
2
  require "itamae/runner"
3
- require "itamae/cli"
4
3
  require "itamae/recipe"
5
4
  require "itamae/resource"
6
5
  require "itamae/handler"
@@ -98,7 +98,7 @@ module Itamae
98
98
  @backend.receive_file(src, dst)
99
99
  end
100
100
 
101
- def send_file(src, dst)
101
+ def send_file(src, dst, user: nil)
102
102
  Itamae.logger.debug "Sending a file from '#{src}' to '#{dst}'..."
103
103
  unless ::File.exist?(src)
104
104
  raise SourceNotExistError, "The file '#{src}' doesn't exist."
@@ -106,7 +106,15 @@ module Itamae
106
106
  unless ::File.file?(src)
107
107
  raise SourceNotExistError, "'#{src}' is not a file."
108
108
  end
109
- @backend.send_file(src, dst)
109
+
110
+ if self.instance_of?(Backend::Local)
111
+ read_command = build_command("cat #{src.shellescape}", {})
112
+ write_command = build_command("cat > #{dst.shellescape}", user: user)
113
+ command = [read_command, write_command].join(' | ')
114
+ run_command(command)
115
+ else
116
+ @backend.send_file(src, dst)
117
+ end
110
118
  end
111
119
 
112
120
  def send_directory(src, dst)
@@ -183,12 +183,12 @@ module Itamae
183
183
 
184
184
  if backend.is_a?(Itamae::Backend::Docker)
185
185
  run_command(["mkdir", @temppath])
186
- backend.send_file(src, @temppath)
186
+ backend.send_file(src, @temppath, user: attributes.user)
187
187
  @temppath = ::File.join(@temppath, ::File.basename(src))
188
188
  else
189
189
  run_command(["touch", @temppath])
190
190
  run_specinfra(:change_file_mode, @temppath, '0600')
191
- backend.send_file(src, @temppath)
191
+ backend.send_file(src, @temppath, user: attributes.user)
192
192
  end
193
193
 
194
194
  run_specinfra(:change_file_mode, @temppath, '0600')
@@ -38,9 +38,14 @@ module Itamae
38
38
 
39
39
  def render_file(src)
40
40
  template = ::File.read(src)
41
- ERB.new(template, nil, '-').tap do |erb|
42
- erb.filename = src
43
- end.result(binding)
41
+ erb =
42
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
43
+ ERB.new(template, trim_mode: '-')
44
+ else
45
+ ERB.new(template, nil, '-')
46
+ end
47
+ erb.filename = src
48
+ erb.result(binding)
44
49
  end
45
50
 
46
51
  def node
@@ -1,3 +1,3 @@
1
1
  module Itamae
2
- VERSION = "1.10.2"
2
+ VERSION = "1.10.3"
3
3
  end
@@ -119,34 +119,6 @@ describe file('/tmp/subscribes') do
119
119
  its(:content) { should eq("2431") }
120
120
  end
121
121
 
122
- describe file('/tmp/cron_stopped') do
123
- it { should be_file }
124
- its(:content) do
125
- expect(subject.content.lines.size).to eq 1
126
- end
127
- end
128
-
129
- # FIXME: cron service is not running in docker...
130
- #
131
- # root@3450c6da6ea5:/# ps -C cron
132
- # PID TTY TIME CMD
133
- # root@3450c6da6ea5:/# service cron start
134
- # Rather than invoking init scripts through /etc/init.d, use the service(8)
135
- # utility, e.g. service cron start
136
- #
137
- # Since the script you are attempting to invoke has been converted to an
138
- # Upstart job, you may also use the start(8) utility, e.g. start cron
139
- # root@3450c6da6ea5:/# ps -C cron
140
- # PID TTY TIME CMD
141
- # root@3450c6da6ea5:/#
142
-
143
- # describe file('/tmp/cron_running') do
144
- # it { should be_file }
145
- # its(:content) do
146
- # expect(subject.content.lines.size).to eq 2
147
- # end
148
- # end
149
-
150
122
  describe file('/tmp-link') do
151
123
  it { should be_linked_to '/tmp' }
152
124
  its(:content) do
@@ -206,15 +178,19 @@ describe command('gem list') do
206
178
  end
207
179
 
208
180
  describe command('gem list') do
209
- its(:stdout) { should include('rake (11.1.0)') }
181
+ its(:stdout) { should match(/^rake \(.*11.1.0.*\)/) }
210
182
  end
211
183
 
212
184
  describe command('gem list') do
213
185
  its(:stdout) { should_not include('test-unit') }
214
186
  end
215
187
 
216
- describe command('ri Bundler') do
217
- its(:stderr) { should eq("Nothing known about Bundler\n") }
188
+ describe command('gem list') do
189
+ its(:stdout) { should include('ast (2.0.0)') }
190
+ end
191
+
192
+ describe command('ri AST') do
193
+ its(:stderr) { should eq("Nothing known about AST\n") }
218
194
  end
219
195
 
220
196
  describe file('/tmp/created_by_definition') do
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe file('/tmp/cron_stopped') do
4
+ it { should be_file }
5
+ its(:content) do
6
+ expect(subject.content.lines.size).to eq 1
7
+ end
8
+ end
9
+
10
+ # FIXME: cron service is not running in docker...
11
+ #
12
+ # root@3450c6da6ea5:/# ps -C cron
13
+ # PID TTY TIME CMD
14
+ # root@3450c6da6ea5:/# service cron start
15
+ # Rather than invoking init scripts through /etc/init.d, use the service(8)
16
+ # utility, e.g. service cron start
17
+ #
18
+ # Since the script you are attempting to invoke has been converted to an
19
+ # Upstart job, you may also use the start(8) utility, e.g. start cron
20
+ # root@3450c6da6ea5:/# ps -C cron
21
+ # PID TTY TIME CMD
22
+ # root@3450c6da6ea5:/#
23
+
24
+ # describe file('/tmp/cron_running') do
25
+ # it { should be_file }
26
+ # its(:content) do
27
+ # expect(subject.content.lines.size).to eq 2
28
+ # end
29
+ # end
@@ -0,0 +1,6 @@
1
+ describe file('/tmp/file_as_ordinary_user') do
2
+ it { should be_file }
3
+ it { should be_owned_by "itamae" }
4
+ it { should be_grouped_into "itamae" }
5
+ end
6
+
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe file('/tmp/remote_file') do
4
+ it { should be_file }
5
+ it { should be_owned_by "ordinary_san" }
6
+ it { should be_grouped_into "ordinary_san" }
7
+ its(:content) { should match(/Hello Itamae/) }
8
+ end
9
+
10
+ describe file('/tmp/remote_file_root') do
11
+ it { should be_file }
12
+ it { should be_owned_by "root" }
13
+ it { should be_grouped_into "root" }
14
+ its(:content) { should match(/Hello Itamae/) }
15
+ end
16
+
17
+ %w[/tmp/remote_file_another_ordinary /tmp/remote_file_another_ordinary_with_root].each do |path|
18
+ describe file(path) do
19
+ it { should be_file }
20
+ it { should be_owned_by "itamae" }
21
+ it { should be_grouped_into "itamae" }
22
+ its(:content) { should match(/Hello Itamae/) }
23
+ end
24
+ end
25
+
26
+ ###
27
+
28
+ describe file('/tmp/file') do
29
+ it { should be_file }
30
+ it { should be_owned_by "ordinary_san" }
31
+ it { should be_grouped_into "ordinary_san" }
32
+ its(:content) { should match(/Hello World/) }
33
+ end
34
+
35
+ describe file('/tmp/file_root') do
36
+ it { should be_file }
37
+ it { should be_owned_by "root" }
38
+ it { should be_grouped_into "root" }
39
+ its(:content) { should match(/Hello World/) }
40
+ end
41
+
42
+ %w[/tmp/file_another_ordinary /tmp/file_another_ordinary_with_root].each do |path|
43
+ describe file(path) do
44
+ it { should be_file }
45
+ it { should be_owned_by "itamae" }
46
+ it { should be_grouped_into "itamae" }
47
+ its(:content) { should match(/Hello World/) }
48
+ end
49
+ end
50
+
51
+ ###
52
+
53
+ describe file('/tmp/template') do
54
+ it { should be_file }
55
+ it { should be_owned_by "ordinary_san" }
56
+ it { should be_grouped_into "ordinary_san" }
57
+ its(:content) { should match(/Hello/) }
58
+ its(:content) { should match(/Good bye/) }
59
+ its(:content) { should match(/^total memory: \d+kB$/) }
60
+ its(:content) { should match(/^uninitialized node key: $/) }
61
+ end
62
+
63
+ describe file('/tmp/template_root') do
64
+ it { should be_file }
65
+ it { should be_owned_by "root" }
66
+ it { should be_grouped_into "root" }
67
+ its(:content) { should match(/Hello/) }
68
+ its(:content) { should match(/Good bye/) }
69
+ its(:content) { should match(/^total memory: \d+kB$/) }
70
+ its(:content) { should match(/^uninitialized node key: $/) }
71
+ end
72
+
73
+ %w[/tmp/template_another_ordinary /tmp/template_another_ordinary_with_root].each do |path|
74
+ describe file(path) do
75
+ it { should be_file }
76
+ it { should be_owned_by "itamae" }
77
+ it { should be_grouped_into "itamae" }
78
+ its(:content) { should match(/Hello/) }
79
+ its(:content) { should match(/Good bye/) }
80
+ its(:content) { should match(/^total memory: \d+kB$/) }
81
+ its(:content) { should match(/^uninitialized node key: $/) }
82
+ end
83
+ end
84
+
85
+ ###
86
+
87
+ describe file('/tmp/http_request.html') do
88
+ it { should be_file }
89
+ it { should be_owned_by "ordinary_san" }
90
+ it { should be_grouped_into "ordinary_san" }
91
+ its(:content) { should match(/"from":\s*"itamae"/) }
92
+ end
93
+
94
+ describe file('/tmp/http_request_root.html') do
95
+ it { should be_file }
96
+ it { should be_owned_by "root" }
97
+ it { should be_grouped_into "root" }
98
+ its(:content) { should match(/"from":\s*"itamae"/) }
99
+ end
100
+
101
+ %w[/tmp/http_request_another_ordinary.html /tmp/http_request_another_ordinary_with_root.html].each do |path|
102
+ describe file(path) do
103
+ it { should be_file }
104
+ it { should be_owned_by "itamae" }
105
+ it { should be_grouped_into "itamae" }
106
+ its(:content) { should match(/"from":\s*"itamae"/) }
107
+ end
108
+ end
@@ -45,10 +45,6 @@ package 'dstat' do
45
45
  action :install
46
46
  end
47
47
 
48
- package 'sl' do
49
- version '3.03-17'
50
- end
51
-
52
48
  package 'resolvconf' do
53
49
  action :remove
54
50
  end
@@ -65,10 +61,6 @@ gem_package 'tzinfo' do
65
61
  version '1.2.2'
66
62
  end
67
63
 
68
- gem_package 'bundler' do
69
- options ['--no-ri', '--no-rdoc']
70
- end
71
-
72
64
  gem_package 'rake' do
73
65
  version '11.1.0'
74
66
  end
@@ -223,42 +215,6 @@ http_request "/tmp/http_request_redirect.html" do
223
215
  url "https://httpbin.org/redirect-to?url=https%3A%2F%2Fhttpbin.org%2Fget%3Ffrom%3Ditamae"
224
216
  end
225
217
 
226
- ######
227
-
228
- service "cron" do
229
- action :stop
230
- end
231
-
232
- execute "ps -C cron > /tmp/cron_stopped; true"
233
-
234
- service "cron" do
235
- action :start
236
- end
237
-
238
- execute "ps -C cron > /tmp/cron_running; true"
239
-
240
- ######
241
-
242
- package "nginx" do
243
- options "--force-yes"
244
- end
245
-
246
- service "nginx" do
247
- action [:enable, :start]
248
- end
249
-
250
- execute "test -f /etc/rc3.d/S20nginx" # test
251
- execute "test $(ps h -C nginx | wc -l) -gt 0" # test
252
-
253
- service "nginx" do
254
- action [:disable, :stop]
255
- end
256
-
257
- execute "test ! -f /etc/rc3.d/S20nginx" # test
258
- execute "test $(ps h -C nginx | wc -l) -eq 0" # test
259
-
260
- ######
261
-
262
218
  link "/tmp-link" do
263
219
  to "/tmp"
264
220
  end
@@ -0,0 +1,44 @@
1
+ package 'sl' do
2
+ version '3.03-17'
3
+ end
4
+
5
+ ######
6
+
7
+ gem_package 'ast' do
8
+ version '2.0.0'
9
+ options ['--no-ri', '--no-rdoc']
10
+ end
11
+
12
+ ######
13
+
14
+ service "cron" do
15
+ action :stop
16
+ end
17
+
18
+ execute "ps -C cron > /tmp/cron_stopped; true"
19
+
20
+ service "cron" do
21
+ action :start
22
+ end
23
+
24
+ execute "ps -C cron > /tmp/cron_running; true"
25
+
26
+ ######
27
+
28
+ package "nginx" do
29
+ options "--force-yes"
30
+ end
31
+
32
+ service "nginx" do
33
+ action [:enable, :start]
34
+ end
35
+
36
+ execute "test -f /etc/rc3.d/S20nginx" # test
37
+ execute "test $(ps h -C nginx | wc -l) -gt 0" # test
38
+
39
+ service "nginx" do
40
+ action [:disable, :stop]
41
+ end
42
+
43
+ execute "test ! -f /etc/rc3.d/S20nginx" # test
44
+ execute "test $(ps h -C nginx | wc -l) -eq 0" # test
@@ -0,0 +1,21 @@
1
+ package 'sl' do
2
+ version '3.03-17+b2'
3
+ end
4
+
5
+ ######
6
+
7
+ gem_package 'ast' do
8
+ version '2.0.0'
9
+ options ['--no-document']
10
+ end
11
+
12
+ ######
13
+
14
+ # Docker backend raises an error with `user` option, so it tests only on `itamae local`.
15
+ # After fix this error, please move this code and the spec to `default.rb`.
16
+ file "/tmp/file_as_ordinary_user" do
17
+ content "Hello World"
18
+ user "itamae"
19
+ owner "itamae"
20
+ group "itamae"
21
+ end
@@ -0,0 +1,109 @@
1
+ remote_file "/tmp/remote_file" do
2
+ source "hello.txt"
3
+ end
4
+
5
+ remote_file "/tmp/remote_file_root" do
6
+ user 'root'
7
+ owner 'root'
8
+ group 'root'
9
+ source "hello.txt"
10
+ end
11
+
12
+ remote_file "/tmp/remote_file_another_ordinary" do
13
+ user 'itamae'
14
+ owner 'itamae'
15
+ group 'itamae'
16
+ source "hello.txt"
17
+ end
18
+
19
+ remote_file "/tmp/remote_file_another_ordinary_with_root" do
20
+ user 'root'
21
+ owner 'itamae'
22
+ group 'itamae'
23
+ source "hello.txt"
24
+ end
25
+
26
+ ###
27
+
28
+ file "/tmp/file" do
29
+ content "Hello World"
30
+ end
31
+
32
+ file "/tmp/file_root" do
33
+ user 'root'
34
+ owner 'root'
35
+ group 'root'
36
+ content 'Hello World'
37
+ end
38
+
39
+ file "/tmp/file_another_ordinary" do
40
+ user 'itamae'
41
+ owner 'itamae'
42
+ group 'itamae'
43
+ content 'Hello World'
44
+ end
45
+
46
+ file "/tmp/file_another_ordinary_with_root" do
47
+ user 'root'
48
+ owner 'itamae'
49
+ group 'itamae'
50
+ content 'Hello World'
51
+ end
52
+
53
+ ###
54
+
55
+ template "/tmp/template" do
56
+ source "hello.erb"
57
+ variables goodbye: "Good bye"
58
+ end
59
+
60
+ template "/tmp/template_root" do
61
+ user 'root'
62
+ owner 'root'
63
+ group 'root'
64
+ source "hello.erb"
65
+ variables goodbye: "Good bye"
66
+ end
67
+
68
+ template "/tmp/template_another_ordinary" do
69
+ user 'itamae'
70
+ owner 'itamae'
71
+ group 'itamae'
72
+ source "hello.erb"
73
+ variables goodbye: "Good bye"
74
+ end
75
+
76
+ template "/tmp/template_another_ordinary_with_root" do
77
+ user 'root'
78
+ owner 'itamae'
79
+ group 'itamae'
80
+ source "hello.erb"
81
+ variables goodbye: "Good bye"
82
+ end
83
+
84
+ ###
85
+
86
+ http_request "/tmp/http_request.html" do
87
+ url "https://httpbin.org/get?from=itamae"
88
+ end
89
+
90
+ http_request "/tmp/http_request_root.html" do
91
+ user 'root'
92
+ owner 'root'
93
+ group 'root'
94
+ url "https://httpbin.org/get?from=itamae"
95
+ end
96
+
97
+ http_request "/tmp/http_request_another_ordinary.html" do
98
+ user 'itamae'
99
+ owner 'itamae'
100
+ group 'itamae'
101
+ url "https://httpbin.org/get?from=itamae"
102
+ end
103
+
104
+ http_request "/tmp/http_request_another_ordinary_with_root.html" do
105
+ user 'root'
106
+ owner 'itamae'
107
+ group 'itamae'
108
+ url "https://httpbin.org/get?from=itamae"
109
+ end
@@ -0,0 +1,117 @@
1
+ desc 'Run all integration tests on `itamae local` command'
2
+ task 'spec:integration:local' => ['spec:integration:local:main', 'spec:integration:local:ordinary_user']
3
+
4
+ namespace 'spec:integration:local' do
5
+ desc 'Run main integration test with `itamae local`'
6
+ task 'main' do
7
+ if RUBY_DESCRIPTION.include?('dev')
8
+ $stderr.puts "This integration test is skipped with unreleased Ruby."
9
+ $stderr.puts "Use released Ruby to execute this integration test."
10
+ next
11
+ end
12
+
13
+ IntegrationLocalSpecRunner.new(
14
+ [
15
+ [
16
+ "spec/integration/recipes/default.rb",
17
+ "spec/integration/recipes/default2.rb",
18
+ "spec/integration/recipes/redefine.rb",
19
+ "spec/integration/recipes/local.rb",
20
+ ],
21
+ [
22
+ "--dry-run",
23
+ "spec/integration/recipes/dry_run.rb",
24
+ ],
25
+ ],
26
+ ['spec/integration/default_spec.rb']
27
+ ).run
28
+
29
+ end
30
+
31
+ desc 'Run integration test for ordinary user with `itamae local`'
32
+ task 'ordinary_user' do
33
+ if RUBY_DESCRIPTION.include?('dev')
34
+ $stderr.puts "This integration test is skipped with unreleased Ruby."
35
+ $stderr.puts "Use released Ruby to execute this integration test."
36
+ next
37
+ end
38
+
39
+ runner = IntegrationLocalSpecRunner.new(
40
+ [
41
+ [
42
+ "--dry-run",
43
+ "spec/integration/recipes/ordinary_user.rb",
44
+ ],
45
+ [
46
+ "spec/integration/recipes/ordinary_user.rb"
47
+ ],
48
+ ],
49
+ ['spec/integration/ordinary_user_spec.rb'],
50
+ user: 'ordinary_san'
51
+ )
52
+ runner.docker_exec 'useradd', 'ordinary_san', '-p', '*'
53
+ runner.docker_exec 'useradd', 'itamae', '-p', '*', '--create-home'
54
+ runner.docker_exec 'sh', '-c', 'echo "ordinary_san ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers'
55
+ runner.run
56
+ end
57
+ end
58
+
59
+ class IntegrationLocalSpecRunner
60
+ CONTAINER_NAME = 'itamae'
61
+ include FileUtils
62
+
63
+ def initialize(suites, specs, ruby_version: RUBY_VERSION.split('.')[0..1].join('.'), user: nil)
64
+ @suites = suites
65
+ @specs = specs
66
+ @ruby_version = ruby_version
67
+ @user = user
68
+
69
+ docker_run
70
+ prepare
71
+ end
72
+
73
+ def run
74
+ provision
75
+ serverspec
76
+ clean_docker_container
77
+ end
78
+
79
+ def docker_run
80
+ mount_dir = Pathname(__dir__).join('../').to_s
81
+ sh 'docker', 'run', '--privileged', '-d', '--name', CONTAINER_NAME, '-v', "#{mount_dir}:/itamae", "ruby:#{@ruby_version}", 'sleep', '1d'
82
+ end
83
+
84
+ def prepare
85
+ docker_exec 'gem', 'install', 'bundler'
86
+ docker_exec 'bundle', 'install', options: %w[--workdir /itamae]
87
+ docker_exec 'apt-get', 'update', '-y'
88
+ docker_exec 'apt-get', 'install', 'locales', 'sudo', '-y'
89
+ docker_exec 'localedef', '-i', 'en_US', '-c', '-f', 'UTF-8', '-A', '/usr/share/locale/locale.alias', 'en_US.UTF-8'
90
+ end
91
+
92
+ def provision
93
+ @suites.each do |suite|
94
+ cmd = %W!bundle exec ruby -w bin/itamae local!
95
+ cmd << "-l" << (ENV['LOG_LEVEL'] || 'debug')
96
+ cmd << "-j" << "spec/integration/recipes/node.json"
97
+ cmd += suite
98
+
99
+ options = %w[--workdir /itamae]
100
+ options.push('--user', @user) if @user
101
+ docker_exec(*cmd, options: options)
102
+ end
103
+ end
104
+
105
+ def serverspec
106
+ ENV['DOCKER_CONTAINER'] = CONTAINER_NAME
107
+ sh('bundle', 'exec', 'rspec', '-I', './spec/integration', *@specs)
108
+ end
109
+
110
+ def clean_docker_container
111
+ sh('docker', 'rm', '-f', CONTAINER_NAME)
112
+ end
113
+
114
+ def docker_exec(*cmd, options: [])
115
+ sh 'docker', 'exec', '--env', 'LANG=en_US.utf8', *options, CONTAINER_NAME, *cmd
116
+ end
117
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itamae
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.2
4
+ version: 1.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryota Arai
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-12-14 00:00:00.000000000 Z
13
+ date: 2019-01-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: thor
@@ -92,14 +92,14 @@ dependencies:
92
92
  name: bundler
93
93
  requirement: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - "~>"
95
+ - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '1.3'
98
98
  type: :development
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - "~>"
102
+ - - ">="
103
103
  - !ruby/object:Gem::Version
104
104
  version: '1.3'
105
105
  - !ruby/object:Gem::Dependency
@@ -271,19 +271,25 @@ files:
271
271
  - lib/itamae/runner.rb
272
272
  - lib/itamae/version.rb
273
273
  - spec/integration/default_spec.rb
274
+ - spec/integration/docker_spec.rb
275
+ - spec/integration/local_spec.rb
276
+ - spec/integration/ordinary_user_spec.rb
274
277
  - spec/integration/recipes/default.rb
275
278
  - spec/integration/recipes/default2.rb
276
279
  - spec/integration/recipes/define/default.rb
277
280
  - spec/integration/recipes/define/files/remote_file_in_definition
278
281
  - spec/integration/recipes/define/files/remote_file_in_definition_2
279
282
  - spec/integration/recipes/define/files/remote_file_in_definition_3
283
+ - spec/integration/recipes/docker.rb
280
284
  - spec/integration/recipes/dry_run.rb
281
285
  - spec/integration/recipes/files/empty_file
282
286
  - spec/integration/recipes/files/remote_file_auto
283
287
  - spec/integration/recipes/hello.erb
284
288
  - spec/integration/recipes/hello.txt
285
289
  - spec/integration/recipes/included.rb
290
+ - spec/integration/recipes/local.rb
286
291
  - spec/integration/recipes/node.json
292
+ - spec/integration/recipes/ordinary_user.rb
287
293
  - spec/integration/recipes/redefine.rb
288
294
  - spec/integration/recipes/templates/empty_file.erb
289
295
  - spec/integration/recipes/templates/template_auto.erb
@@ -300,6 +306,7 @@ files:
300
306
  - spec/unit/lib/itamae/resource_spec.rb
301
307
  - spec/unit/lib/itamae/runner_spec.rb
302
308
  - spec/unit/spec_helper.rb
309
+ - tasks/integration_local_spec.rb
303
310
  homepage: https://itamae.kitchen/
304
311
  licenses:
305
312
  - MIT
@@ -322,26 +329,31 @@ required_rubygems_version: !ruby/object:Gem::Requirement
322
329
  - !ruby/object:Gem::Version
323
330
  version: '0'
324
331
  requirements: []
325
- rubyforge_project:
326
- rubygems_version: 2.7.6
332
+ rubygems_version: 3.0.1
327
333
  signing_key:
328
334
  specification_version: 4
329
335
  summary: Simple Configuration Management Tool
330
336
  test_files:
331
337
  - spec/integration/default_spec.rb
338
+ - spec/integration/docker_spec.rb
339
+ - spec/integration/local_spec.rb
340
+ - spec/integration/ordinary_user_spec.rb
332
341
  - spec/integration/recipes/default.rb
333
342
  - spec/integration/recipes/default2.rb
334
343
  - spec/integration/recipes/define/default.rb
335
344
  - spec/integration/recipes/define/files/remote_file_in_definition
336
345
  - spec/integration/recipes/define/files/remote_file_in_definition_2
337
346
  - spec/integration/recipes/define/files/remote_file_in_definition_3
347
+ - spec/integration/recipes/docker.rb
338
348
  - spec/integration/recipes/dry_run.rb
339
349
  - spec/integration/recipes/files/empty_file
340
350
  - spec/integration/recipes/files/remote_file_auto
341
351
  - spec/integration/recipes/hello.erb
342
352
  - spec/integration/recipes/hello.txt
343
353
  - spec/integration/recipes/included.rb
354
+ - spec/integration/recipes/local.rb
344
355
  - spec/integration/recipes/node.json
356
+ - spec/integration/recipes/ordinary_user.rb
345
357
  - spec/integration/recipes/redefine.rb
346
358
  - spec/integration/recipes/templates/empty_file.erb
347
359
  - spec/integration/recipes/templates/template_auto.erb