itamae 1.14.1 → 1.15.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/.github/dependabot.yml +10 -0
- data/.github/workflows/docker-daemon.json +3 -0
- data/.github/workflows/release.yml +41 -0
- data/.github/workflows/test.yml +38 -171
- data/.github/workflows/test_main.yml +148 -0
- data/CHANGELOG.md +22 -1
- data/Gemfile +9 -0
- data/README.md +1 -1
- data/Rakefile +11 -1
- data/itamae.gemspec +2 -2
- data/lib/itamae/backend.rb +3 -1
- data/lib/itamae/node.rb +1 -1
- data/lib/itamae/notification.rb +1 -2
- data/lib/itamae/recipe.rb +1 -1
- data/lib/itamae/resource/file.rb +12 -0
- data/lib/itamae/resource/group.rb +3 -1
- data/lib/itamae/runner.rb +2 -2
- data/lib/itamae/version.rb +1 -1
- data/spec/integration/default_spec.rb +22 -8
- data/spec/integration/ordinary_user_spec.rb +3 -3
- data/spec/integration/recipes/default.rb +30 -7
- data/spec/integration/recipes/docker.rb +1 -0
- data/spec/integration/recipes/local.rb +1 -0
- data/spec/integration/recipes/ordinary_user.rb +6 -4
- data/tasks/httpbin_server.rb +63 -0
- data/tasks/integration_local_spec.rb +46 -32
- metadata +12 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 12b8fcd57c70cc4c440ccd46a34786f1ac43a6bc7f4b66b68598ffeecfe9daaf
|
|
4
|
+
data.tar.gz: c1e77510842948b7cc4222e566939e8e32c1540d4b09178dc6492449b38d98c2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d033e29941f7cc56de7626d1b3bdee2e00d1adca58e13c2927c4f3a1202046d80427eb614111424c8e21cc43c2bf480009069782fa5faebfdbf2f9dcd7fdbc5
|
|
7
|
+
data.tar.gz: bd55aa58068d1ec98b5bc74e4e6829d7e0927f575e352289b74801916ebab2f9e511a4b197a947da538c033b0d054af39dc91209facc0e1e74b797c0da07b599
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# c.f. https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
2
|
+
version: 2
|
|
3
|
+
|
|
4
|
+
updates:
|
|
5
|
+
- package-ecosystem: github-actions
|
|
6
|
+
directory: /
|
|
7
|
+
schedule:
|
|
8
|
+
interval: monthly
|
|
9
|
+
cooldown:
|
|
10
|
+
default-days: 7
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Publish gem to rubygems.org
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
release:
|
|
8
|
+
if: github.repository == 'itamae-kitchen/itamae'
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
environment:
|
|
12
|
+
name: rubygems.org
|
|
13
|
+
url: https://rubygems.org/gems/itamae
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Harden Runner
|
|
21
|
+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
|
|
22
|
+
with:
|
|
23
|
+
egress-policy: audit
|
|
24
|
+
|
|
25
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
|
+
|
|
27
|
+
- name: Set up Ruby
|
|
28
|
+
uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
29
|
+
with:
|
|
30
|
+
bundler-cache: true
|
|
31
|
+
ruby-version: ruby
|
|
32
|
+
|
|
33
|
+
- name: Publish to RubyGems
|
|
34
|
+
uses: rubygems/release-gem@052cc82692552de3ef2b81fd670e41d13cba8092 # v1.4.0
|
|
35
|
+
|
|
36
|
+
- name: Create GitHub release
|
|
37
|
+
run: |
|
|
38
|
+
tag_name="$(git describe --tags --abbrev=0)"
|
|
39
|
+
gh release create "${tag_name}" --verify-tag --generate-notes
|
|
40
|
+
env:
|
|
41
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
data/.github/workflows/test.yml
CHANGED
|
@@ -11,11 +11,10 @@ on:
|
|
|
11
11
|
- reopened
|
|
12
12
|
schedule:
|
|
13
13
|
- cron: "0 0 * * 5" # JST 9:00 (Fri)
|
|
14
|
+
workflow_dispatch:
|
|
14
15
|
|
|
15
16
|
jobs:
|
|
16
|
-
|
|
17
|
-
runs-on: ubuntu-latest
|
|
18
|
-
|
|
17
|
+
test_main:
|
|
19
18
|
strategy:
|
|
20
19
|
fail-fast: false
|
|
21
20
|
|
|
@@ -28,10 +27,15 @@ jobs:
|
|
|
28
27
|
- "2.7"
|
|
29
28
|
- "3.0"
|
|
30
29
|
- "3.1"
|
|
30
|
+
- "3.2"
|
|
31
|
+
- "3.3"
|
|
32
|
+
- "3.4"
|
|
33
|
+
- "4.0"
|
|
31
34
|
rubyopt:
|
|
32
35
|
- ""
|
|
33
36
|
- "--jit"
|
|
34
37
|
- "--yjit"
|
|
38
|
+
- "--zjit"
|
|
35
39
|
exclude:
|
|
36
40
|
# --jit is available since MRI 2.6
|
|
37
41
|
- ruby: "2.3"
|
|
@@ -53,194 +57,57 @@ jobs:
|
|
|
53
57
|
rubyopt: "--yjit"
|
|
54
58
|
- ruby: "3.0"
|
|
55
59
|
rubyopt: "--yjit"
|
|
56
|
-
env:
|
|
57
|
-
RUBYOPT: ${{ matrix.rubyopt }}
|
|
58
|
-
|
|
59
|
-
steps:
|
|
60
|
-
- uses: actions/checkout@v2
|
|
61
|
-
|
|
62
|
-
- uses: ruby/setup-ruby@v1
|
|
63
|
-
with:
|
|
64
|
-
ruby-version: ${{ matrix.ruby }}
|
|
65
|
-
bundler-cache: true
|
|
66
|
-
|
|
67
|
-
- run: bundle update
|
|
68
|
-
|
|
69
|
-
- run: bundle exec rake spec:unit
|
|
70
|
-
|
|
71
|
-
- name: Slack Notification (not success)
|
|
72
|
-
uses: lazy-actions/slatify@master
|
|
73
|
-
if: "! success()"
|
|
74
|
-
continue-on-error: true
|
|
75
|
-
with:
|
|
76
|
-
job_name: ${{ format('*unit* ({0},{1})', matrix.ruby, matrix.rubyopt) }}
|
|
77
|
-
type: ${{ job.status }}
|
|
78
|
-
icon_emoji: ":octocat:"
|
|
79
|
-
url: ${{ secrets.SLACK_WEBHOOK }}
|
|
80
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
81
|
-
|
|
82
|
-
integration-docker:
|
|
83
|
-
runs-on: ubuntu-latest
|
|
84
60
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
matrix:
|
|
89
|
-
ruby:
|
|
90
|
-
- "2.3"
|
|
91
|
-
- "2.4"
|
|
92
|
-
- "2.5"
|
|
93
|
-
- "2.6"
|
|
94
|
-
- "2.7"
|
|
95
|
-
- "3.0"
|
|
96
|
-
- "3.1"
|
|
97
|
-
rubyopt:
|
|
98
|
-
- ""
|
|
99
|
-
- "--jit"
|
|
100
|
-
- "--yjit"
|
|
101
|
-
image:
|
|
102
|
-
- ubuntu:trusty
|
|
103
|
-
exclude:
|
|
104
|
-
# --jit is available since MRI 2.6
|
|
105
|
-
- ruby: "2.3"
|
|
106
|
-
rubyopt: "--jit"
|
|
107
|
-
- ruby: "2.4"
|
|
108
|
-
rubyopt: "--jit"
|
|
109
|
-
- ruby: "2.5"
|
|
110
|
-
rubyopt: "--jit"
|
|
111
|
-
# --yjit is available since MRI 3.1
|
|
112
|
-
- ruby: "2.3"
|
|
61
|
+
# --jit is same to --yjit since MRI 3.2 (don't test both `--jit` and `--yjit`)
|
|
62
|
+
- ruby: "3.2"
|
|
113
63
|
rubyopt: "--yjit"
|
|
114
|
-
- ruby: "
|
|
115
|
-
rubyopt: "--yjit"
|
|
116
|
-
- ruby: "2.5"
|
|
64
|
+
- ruby: "3.3"
|
|
117
65
|
rubyopt: "--yjit"
|
|
118
|
-
- ruby: "
|
|
119
|
-
rubyopt: "--yjit"
|
|
120
|
-
- ruby: "2.7"
|
|
66
|
+
- ruby: "3.4"
|
|
121
67
|
rubyopt: "--yjit"
|
|
122
|
-
- ruby: "
|
|
68
|
+
- ruby: "4.0"
|
|
123
69
|
rubyopt: "--yjit"
|
|
124
70
|
|
|
125
|
-
|
|
126
|
-
RUBYOPT: ${{ matrix.rubyopt }}
|
|
127
|
-
TEST_IMAGE: ${{ matrix.image }}
|
|
128
|
-
|
|
129
|
-
steps:
|
|
130
|
-
- uses: actions/checkout@v2
|
|
131
|
-
|
|
132
|
-
- uses: ruby/setup-ruby@v1
|
|
133
|
-
with:
|
|
134
|
-
ruby-version: ${{ matrix.ruby }}
|
|
135
|
-
bundler-cache: true
|
|
136
|
-
|
|
137
|
-
- run: bundle update
|
|
138
|
-
|
|
139
|
-
- run: bundle exec rake spec:integration:docker:boot
|
|
140
|
-
|
|
141
|
-
- run: bundle exec rake spec:integration:docker:provision
|
|
142
|
-
env:
|
|
143
|
-
# FIXME: avoid error for "Command `chmod 777 /tmp/itamae_tmp` failed. (exit status: 1)"
|
|
144
|
-
ITAMAE_TMP_DIR: /var/tmp/itamae_tmp
|
|
145
|
-
|
|
146
|
-
- run: bundle exec rake spec:integration:docker:serverspec
|
|
147
|
-
- run: bundle exec rake spec:integration:docker:clean_docker_container
|
|
148
|
-
|
|
149
|
-
- name: Slack Notification (not success)
|
|
150
|
-
uses: lazy-actions/slatify@master
|
|
151
|
-
if: "! success()"
|
|
152
|
-
continue-on-error: true
|
|
153
|
-
with:
|
|
154
|
-
job_name: ${{ format('*integration-docker* ({0},{1},{2})', matrix.ruby, matrix.rubyopt, matrix.image) }}
|
|
155
|
-
type: ${{ job.status }}
|
|
156
|
-
icon_emoji: ":octocat:"
|
|
157
|
-
url: ${{ secrets.SLACK_WEBHOOK }}
|
|
158
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
159
|
-
|
|
160
|
-
integration-local:
|
|
161
|
-
runs-on: ubuntu-latest
|
|
162
|
-
|
|
163
|
-
strategy:
|
|
164
|
-
fail-fast: false
|
|
165
|
-
|
|
166
|
-
matrix:
|
|
167
|
-
ruby:
|
|
168
|
-
- "2.3"
|
|
169
|
-
- "2.4"
|
|
170
|
-
- "2.5"
|
|
171
|
-
- "2.6"
|
|
172
|
-
- "2.7"
|
|
173
|
-
- "3.0"
|
|
174
|
-
- "3.1"
|
|
175
|
-
rubyopt:
|
|
176
|
-
- ""
|
|
177
|
-
- "--jit"
|
|
178
|
-
- "--yjit"
|
|
179
|
-
exclude:
|
|
180
|
-
# --jit is available since MRI 2.6
|
|
71
|
+
# --zjit is available since MRI 4.0
|
|
181
72
|
- ruby: "2.3"
|
|
182
|
-
rubyopt: "--
|
|
73
|
+
rubyopt: "--zjit"
|
|
183
74
|
- ruby: "2.4"
|
|
184
|
-
rubyopt: "--
|
|
75
|
+
rubyopt: "--zjit"
|
|
185
76
|
- ruby: "2.5"
|
|
186
|
-
rubyopt: "--
|
|
187
|
-
# --yjit is available since MRI 3.1
|
|
188
|
-
- ruby: "2.3"
|
|
189
|
-
rubyopt: "--yjit"
|
|
190
|
-
- ruby: "2.4"
|
|
191
|
-
rubyopt: "--yjit"
|
|
192
|
-
- ruby: "2.5"
|
|
193
|
-
rubyopt: "--yjit"
|
|
77
|
+
rubyopt: "--zjit"
|
|
194
78
|
- ruby: "2.6"
|
|
195
|
-
rubyopt: "--
|
|
79
|
+
rubyopt: "--zjit"
|
|
196
80
|
- ruby: "2.7"
|
|
197
|
-
rubyopt: "--
|
|
81
|
+
rubyopt: "--zjit"
|
|
198
82
|
- ruby: "3.0"
|
|
199
|
-
rubyopt: "--
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
- run: bundle exec rake spec:integration:local:ordinary_user
|
|
216
|
-
|
|
217
|
-
- name: Slack Notification (not success)
|
|
218
|
-
uses: lazy-actions/slatify@master
|
|
219
|
-
if: "! success()"
|
|
220
|
-
continue-on-error: true
|
|
221
|
-
with:
|
|
222
|
-
job_name: ${{ format('*integration-local* ({0},{1})', matrix.ruby, matrix.rubyopt) }}
|
|
223
|
-
type: ${{ job.status }}
|
|
224
|
-
icon_emoji: ":octocat:"
|
|
225
|
-
url: ${{ secrets.SLACK_WEBHOOK }}
|
|
226
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
83
|
+
rubyopt: "--zjit"
|
|
84
|
+
- ruby: "3.1"
|
|
85
|
+
rubyopt: "--zjit"
|
|
86
|
+
- ruby: "3.2"
|
|
87
|
+
rubyopt: "--zjit"
|
|
88
|
+
- ruby: "3.3"
|
|
89
|
+
rubyopt: "--zjit"
|
|
90
|
+
- ruby: "3.4"
|
|
91
|
+
rubyopt: "--zjit"
|
|
92
|
+
|
|
93
|
+
uses: ./.github/workflows/test_main.yml
|
|
94
|
+
with:
|
|
95
|
+
ruby: ${{ matrix.ruby }}
|
|
96
|
+
rubyopt: ${{ matrix.rubyopt }}
|
|
97
|
+
secrets:
|
|
98
|
+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
227
99
|
|
|
228
100
|
notify:
|
|
229
101
|
needs:
|
|
230
|
-
-
|
|
231
|
-
- integration-docker
|
|
232
|
-
- integration-local
|
|
102
|
+
- test_main
|
|
233
103
|
|
|
234
104
|
runs-on: ubuntu-latest
|
|
235
105
|
|
|
236
106
|
steps:
|
|
237
107
|
- name: Slack Notification (success)
|
|
238
|
-
uses:
|
|
108
|
+
uses: act10ns/slack@d96404edccc6d6467fc7f8134a420c851b1e9054 # v2.2.0
|
|
239
109
|
if: always()
|
|
240
110
|
continue-on-error: true
|
|
241
111
|
with:
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
icon_emoji: ":octocat:"
|
|
245
|
-
url: ${{ secrets.SLACK_WEBHOOK }}
|
|
246
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
112
|
+
status: ${{ job.status }}
|
|
113
|
+
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
name: test_main
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
ruby:
|
|
7
|
+
required: true
|
|
8
|
+
type: string
|
|
9
|
+
rubyopt:
|
|
10
|
+
required: false
|
|
11
|
+
type: string
|
|
12
|
+
default: ""
|
|
13
|
+
secrets:
|
|
14
|
+
SLACK_WEBHOOK:
|
|
15
|
+
required: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
unit:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
23
|
+
|
|
24
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
25
|
+
with:
|
|
26
|
+
ruby-version: ${{ inputs.ruby }}
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
bundler: default
|
|
29
|
+
|
|
30
|
+
- run: bundle update
|
|
31
|
+
|
|
32
|
+
- run: bundle exec rake spec:unit
|
|
33
|
+
env:
|
|
34
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
35
|
+
|
|
36
|
+
- name: Slack Notification (not success)
|
|
37
|
+
uses: act10ns/slack@d96404edccc6d6467fc7f8134a420c851b1e9054 # v2.2.0
|
|
38
|
+
if: "! success()"
|
|
39
|
+
continue-on-error: true
|
|
40
|
+
with:
|
|
41
|
+
status: ${{ job.status }}
|
|
42
|
+
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
|
|
43
|
+
inputs: ${{ toJson(inputs) }}
|
|
44
|
+
|
|
45
|
+
integration-docker:
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
|
|
48
|
+
strategy:
|
|
49
|
+
fail-fast: false
|
|
50
|
+
|
|
51
|
+
matrix:
|
|
52
|
+
image:
|
|
53
|
+
- ubuntu:trusty
|
|
54
|
+
|
|
55
|
+
env:
|
|
56
|
+
TEST_IMAGE: ${{ matrix.image }}
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
60
|
+
|
|
61
|
+
- name: Pull Docker Hub images through mirror.gcr.io
|
|
62
|
+
run: |
|
|
63
|
+
sudo cp .github/workflows/docker-daemon.json /etc/docker/daemon.json
|
|
64
|
+
sudo systemctl restart docker
|
|
65
|
+
|
|
66
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
67
|
+
with:
|
|
68
|
+
ruby-version: ${{ inputs.ruby }}
|
|
69
|
+
bundler-cache: true
|
|
70
|
+
bundler: default
|
|
71
|
+
|
|
72
|
+
- run: bundle update
|
|
73
|
+
|
|
74
|
+
- run: bundle exec rake spec:integration:docker:httpbin_start
|
|
75
|
+
env:
|
|
76
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
77
|
+
|
|
78
|
+
- run: bundle exec rake spec:integration:docker:boot
|
|
79
|
+
env:
|
|
80
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
81
|
+
|
|
82
|
+
- run: bundle exec rake spec:integration:docker:provision
|
|
83
|
+
env:
|
|
84
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
85
|
+
|
|
86
|
+
# FIXME: avoid error for "Command `chmod 777 /tmp/itamae_tmp` failed. (exit status: 1)"
|
|
87
|
+
ITAMAE_TMP_DIR: /var/tmp/itamae_tmp
|
|
88
|
+
|
|
89
|
+
- run: bundle exec rake spec:integration:docker:serverspec
|
|
90
|
+
env:
|
|
91
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
92
|
+
|
|
93
|
+
- run: bundle exec rake spec:integration:docker:clean_docker_container
|
|
94
|
+
env:
|
|
95
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
96
|
+
|
|
97
|
+
- run: bundle exec rake spec:integration:docker:httpbin_stop
|
|
98
|
+
if: always()
|
|
99
|
+
env:
|
|
100
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
101
|
+
|
|
102
|
+
- name: Slack Notification (not success)
|
|
103
|
+
uses: act10ns/slack@d96404edccc6d6467fc7f8134a420c851b1e9054 # v2.2.0
|
|
104
|
+
if: "! success()"
|
|
105
|
+
continue-on-error: true
|
|
106
|
+
with:
|
|
107
|
+
status: ${{ job.status }}
|
|
108
|
+
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
|
|
109
|
+
matrix: ${{ toJson(matrix) }}
|
|
110
|
+
|
|
111
|
+
integration-local:
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
|
|
114
|
+
# NOTE: When ruby is 2.5, tests run on buster. But buster is already EOL and didn't work apt-get
|
|
115
|
+
if: ${{ inputs.ruby >= '2.6' }}
|
|
116
|
+
|
|
117
|
+
steps:
|
|
118
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
119
|
+
|
|
120
|
+
- name: Pull Docker Hub images through mirror.gcr.io
|
|
121
|
+
run: |
|
|
122
|
+
sudo cp .github/workflows/docker-daemon.json /etc/docker/daemon.json
|
|
123
|
+
sudo systemctl restart docker
|
|
124
|
+
|
|
125
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
126
|
+
with:
|
|
127
|
+
ruby-version: ${{ inputs.ruby }}
|
|
128
|
+
bundler-cache: true
|
|
129
|
+
bundler: default
|
|
130
|
+
|
|
131
|
+
- run: bundle update
|
|
132
|
+
|
|
133
|
+
- run: bundle exec rake spec:integration:local:main
|
|
134
|
+
env:
|
|
135
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
136
|
+
|
|
137
|
+
- run: bundle exec rake spec:integration:local:ordinary_user
|
|
138
|
+
env:
|
|
139
|
+
RUBYOPT: ${{ inputs.rubyopt }}
|
|
140
|
+
|
|
141
|
+
- name: Slack Notification (not success)
|
|
142
|
+
uses: act10ns/slack@d96404edccc6d6467fc7f8134a420c851b1e9054 # v2.2.0
|
|
143
|
+
if: "! success()"
|
|
144
|
+
continue-on-error: true
|
|
145
|
+
with:
|
|
146
|
+
status: ${{ job.status }}
|
|
147
|
+
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
|
|
148
|
+
inputs: ${{ toJson(inputs) }}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
## Unreleased
|
|
2
|
-
[full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.
|
|
2
|
+
[full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.15.0...master)
|
|
3
|
+
|
|
4
|
+
## v1.15.0
|
|
5
|
+
[full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.14.2...v1.15.0)
|
|
6
|
+
|
|
7
|
+
Improvements
|
|
8
|
+
|
|
9
|
+
- [Add `system_group` option to `group` resource by takumin](https://github.com/itamae-kitchen/itamae/pull/297)
|
|
10
|
+
- NOTE: This bumps the minimum required specinfra version to 2.81.0.
|
|
11
|
+
- [Add 'etc' library requirement in backend.rb by neidiom](https://github.com/itamae-kitchen/itamae/pull/389)
|
|
12
|
+
- [Prefer `Bundler.with_unbundled_env` over deprecated `with_clean_env` by neidiom](https://github.com/itamae-kitchen/itamae/pull/390)
|
|
13
|
+
- [Convert ohai commands to array form in runner by neidiom](https://github.com/itamae-kitchen/itamae/pull/395)
|
|
14
|
+
- [Use `respond_to_missing?` instead of `respond_to?` in Node by neidiom](https://github.com/itamae-kitchen/itamae/pull/409)
|
|
15
|
+
- [Replace abort with raise in notification validation by neidiom](https://github.com/itamae-kitchen/itamae/pull/410)
|
|
16
|
+
- [Fix shadowed variable in `include_recipe` find block by neidiom](https://github.com/itamae-kitchen/itamae/pull/408)
|
|
17
|
+
|
|
18
|
+
## v1.14.2
|
|
19
|
+
[full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.14.1...v1.14.2)
|
|
20
|
+
|
|
21
|
+
Bugfixes
|
|
22
|
+
|
|
23
|
+
- [Add workaround for `Gem::Package::TarWriter#add_file`](https://github.com/itamae-kitchen/itamae/pull/378)
|
|
3
24
|
|
|
4
25
|
## v1.14.1
|
|
5
26
|
[full changelog](https://github.com/itamae-kitchen/itamae/compare/v1.14.0...v1.14.1)
|
data/Gemfile
CHANGED
|
@@ -11,3 +11,12 @@ group :test do
|
|
|
11
11
|
gem 'growl'
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
|
+
|
|
15
|
+
# FIXME: Delete the following after https://github.com/fakefs/fakefs/pull/494 is merged and released
|
|
16
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0.preview2")
|
|
17
|
+
gem "english"
|
|
18
|
+
gem "fileutils"
|
|
19
|
+
gem "find"
|
|
20
|
+
gem "irb"
|
|
21
|
+
gem "stringio"
|
|
22
|
+
end
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# [](https://github.com/itamae-kitchen/itamae)
|
|
2
2
|
|
|
3
|
-
[](http://badge.fury.io/rb/itamae) [](http://badge.fury.io/rb/itamae) [](https://codeclimate.com/github/itamae-kitchen/itamae/maintainability) [](https://github.com/itamae-kitchen/itamae/actions/workflows/test.yml) [](https://join.slack.com/t/itamae/shared_invite/enQtNTExNTI3ODM1NTY5LTM5MWJlZTgwODE0YTUwMThiNzZjN2I1MGNlZjE2NjlmNzg5NTNlOTliMDhkNDNmNTQ2ZTgwMzZjNjI5NDJiZGI)
|
|
4
4
|
|
|
5
5
|
Simple and lightweight configuration management tool inspired by Chef.
|
|
6
6
|
|
data/Rakefile
CHANGED
|
@@ -24,9 +24,19 @@ namespace :spec do
|
|
|
24
24
|
task :all => ['spec:integration:docker', 'spec:integration:local']
|
|
25
25
|
|
|
26
26
|
desc "Run provision and specs"
|
|
27
|
-
task :docker => ["docker:boot", "docker:provision", "docker:serverspec", 'docker:clean_docker_container']
|
|
27
|
+
task :docker => ["docker:httpbin_start", "docker:boot", "docker:provision", "docker:serverspec", 'docker:clean_docker_container', "docker:httpbin_stop"]
|
|
28
28
|
|
|
29
29
|
namespace :docker do
|
|
30
|
+
desc "Start a local go-httpbin server for http_request tests"
|
|
31
|
+
task :httpbin_start do
|
|
32
|
+
HttpbinServer.start
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
desc "Stop the local go-httpbin server"
|
|
36
|
+
task :httpbin_stop do
|
|
37
|
+
HttpbinServer.stop
|
|
38
|
+
end
|
|
39
|
+
|
|
30
40
|
desc "Run docker"
|
|
31
41
|
task :boot do
|
|
32
42
|
sh "docker run --privileged -d --name #{container_name} #{TEST_IMAGE} /sbin/init"
|
data/itamae.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.require_paths = ["lib"]
|
|
29
29
|
|
|
30
30
|
spec.add_runtime_dependency "thor", ">= 1.0.0"
|
|
31
|
-
spec.add_runtime_dependency "specinfra", [">= 2.
|
|
31
|
+
spec.add_runtime_dependency "specinfra", [">= 2.81.0", "< 3.0.0"]
|
|
32
32
|
spec.add_runtime_dependency "hashie"
|
|
33
33
|
spec.add_runtime_dependency "ansi"
|
|
34
34
|
spec.add_runtime_dependency "schash", "~> 0.1.0"
|
|
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
|
36
36
|
spec.add_development_dependency "bundler", ">= 1.3"
|
|
37
37
|
spec.add_development_dependency "rake"
|
|
38
38
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
39
|
-
spec.add_development_dependency "serverspec", "~> 2.
|
|
39
|
+
spec.add_development_dependency "serverspec", "~> 2.43"
|
|
40
40
|
spec.add_development_dependency "pry-byebug"
|
|
41
41
|
spec.add_development_dependency "docker-api", "~> 2"
|
|
42
42
|
spec.add_development_dependency "fakefs"
|
data/lib/itamae/backend.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'specinfra/core'
|
|
|
2
2
|
require 'singleton'
|
|
3
3
|
require 'io/console'
|
|
4
4
|
require 'net/ssh'
|
|
5
|
+
require 'etc'
|
|
5
6
|
|
|
6
7
|
Specinfra::Configuration.error_on_missing_backend_type = true
|
|
7
8
|
|
|
@@ -267,7 +268,8 @@ module Itamae
|
|
|
267
268
|
hostname = opts[:host_name] || 'default'
|
|
268
269
|
vagrant_cmd = "vagrant ssh-config #{hostname} > #{config.path}"
|
|
269
270
|
if defined?(Bundler)
|
|
270
|
-
Bundler.with_clean_env
|
|
271
|
+
bundler_method = Bundler.respond_to?(:with_unbundled_env) ? :with_unbundled_env : :with_clean_env
|
|
272
|
+
Bundler.public_send(bundler_method) do
|
|
271
273
|
`#{vagrant_cmd}`
|
|
272
274
|
end
|
|
273
275
|
else
|
data/lib/itamae/node.rb
CHANGED
data/lib/itamae/notification.rb
CHANGED
|
@@ -30,8 +30,7 @@ module Itamae
|
|
|
30
30
|
|
|
31
31
|
def validate!
|
|
32
32
|
unless [:delay, :delayed, :immediately].include?(timing)
|
|
33
|
-
|
|
34
|
-
abort
|
|
33
|
+
raise ArgumentError, "'#{timing}' is not valid notification timing. (Valid option is delayed or immediately)"
|
|
35
34
|
end
|
|
36
35
|
end
|
|
37
36
|
end
|
data/lib/itamae/recipe.rb
CHANGED
|
@@ -122,7 +122,7 @@ module Itamae
|
|
|
122
122
|
expanded_path = ::File.join(expanded_path, 'default.rb') if ::Dir.exist?(expanded_path)
|
|
123
123
|
expanded_path.concat('.rb') unless expanded_path.end_with?('.rb')
|
|
124
124
|
candidate_paths = [expanded_path, Recipe.find_recipe_in_gem(target)].compact
|
|
125
|
-
path = candidate_paths.find {|
|
|
125
|
+
path = candidate_paths.find {|candidate_path| File.exist?(candidate_path) }
|
|
126
126
|
|
|
127
127
|
unless path
|
|
128
128
|
raise NotFoundError, "Recipe not found. (#{target})"
|
data/lib/itamae/resource/file.rb
CHANGED
|
@@ -214,7 +214,19 @@ module Itamae
|
|
|
214
214
|
|
|
215
215
|
if backend.is_a?(Itamae::Backend::Docker)
|
|
216
216
|
run_command(["mkdir", @temppath])
|
|
217
|
+
|
|
218
|
+
# NOTE: From rubygems v3.6.7, Gem::Package::TarWriter#add_file uses SOURCE_DATE_EPOCH env var to set file mtime.
|
|
219
|
+
# This is a workaround for Docker backend where Gem::Package::TarWriter#add_file used in Docker backend.
|
|
220
|
+
# See also:
|
|
221
|
+
# * https://github.com/ruby/rubygems/pull/8673
|
|
222
|
+
# * https://github.com/itamae-kitchen/itamae/issues/377
|
|
223
|
+
# * https://github.com/itamae-kitchen/itamae/pull/378
|
|
224
|
+
current_source_date_epoch_env = ENV["SOURCE_DATE_EPOCH"]
|
|
225
|
+
ENV["SOURCE_DATE_EPOCH"] = Time.now.to_i.to_s unless current_source_date_epoch_env
|
|
217
226
|
backend.send_file(src, @temppath, user: attributes.user)
|
|
227
|
+
ENV["SOURCE_DATE_EPOCH"] = current_source_date_epoch_env
|
|
228
|
+
# end of NOTE
|
|
229
|
+
|
|
218
230
|
@temppath = ::File.join(@temppath, ::File.basename(src))
|
|
219
231
|
else
|
|
220
232
|
run_command(["touch", @temppath])
|
|
@@ -4,6 +4,7 @@ module Itamae
|
|
|
4
4
|
define_attribute :action, default: :create
|
|
5
5
|
define_attribute :groupname, type: String, default_name: true
|
|
6
6
|
define_attribute :gid, type: Integer
|
|
7
|
+
define_attribute :system_group, type: [TrueClass, FalseClass]
|
|
7
8
|
|
|
8
9
|
def set_current_attributes
|
|
9
10
|
current.exist = exist?
|
|
@@ -21,7 +22,8 @@ module Itamae
|
|
|
21
22
|
end
|
|
22
23
|
else
|
|
23
24
|
options = {
|
|
24
|
-
gid:
|
|
25
|
+
gid: attributes.gid,
|
|
26
|
+
system_group: attributes.system_group,
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
run_specinfra(:add_group, attributes.groupname, options)
|
data/lib/itamae/runner.rb
CHANGED
|
@@ -101,14 +101,14 @@ module Itamae
|
|
|
101
101
|
hash.extend(Hashie::Extensions::DeepMerge)
|
|
102
102
|
|
|
103
103
|
if @options[:ohai]
|
|
104
|
-
unless @backend.run_command("which ohai", error: false).exit_status == 0
|
|
104
|
+
unless @backend.run_command(["which", "ohai"], error: false).exit_status == 0
|
|
105
105
|
# install Ohai
|
|
106
106
|
Itamae.logger.info "Installing Chef package... (to use Ohai)"
|
|
107
107
|
@backend.run_command("curl -L https://omnitruck.chef.io/install.sh | bash")
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
Itamae.logger.info "Loading node data via ohai..."
|
|
111
|
-
hash.merge!(JSON.parse(@backend.run_command("ohai
|
|
111
|
+
hash.merge!(JSON.parse(@backend.run_command(["ohai"], error: false).stdout))
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
@options.fetch(:node_json, []).each do |name|
|
data/lib/itamae/version.rb
CHANGED
|
@@ -7,11 +7,21 @@ describe user("itamae") do
|
|
|
7
7
|
it { should have_login_shell '/bin/dash' }
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
describe user("itamae_system") do
|
|
11
|
+
it { should exist }
|
|
12
|
+
it { should be_is_system_user }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe group("itamae_system") do
|
|
16
|
+
it { should exist }
|
|
17
|
+
it { should be_is_system_group }
|
|
18
|
+
end
|
|
19
|
+
|
|
10
20
|
describe file('/tmp/included_recipe') do
|
|
11
21
|
it { should be_file }
|
|
12
22
|
end
|
|
13
23
|
|
|
14
|
-
describe package('
|
|
24
|
+
describe package('jq') do
|
|
15
25
|
it { should be_installed }
|
|
16
26
|
end
|
|
17
27
|
|
|
@@ -79,29 +89,29 @@ end
|
|
|
79
89
|
|
|
80
90
|
describe file('/tmp/http_request.html') do
|
|
81
91
|
it { should be_file }
|
|
82
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
92
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
83
93
|
end
|
|
84
94
|
|
|
85
95
|
describe file('/tmp/http_request_delete.html') do
|
|
86
96
|
it { should be_file }
|
|
87
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
97
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
88
98
|
end
|
|
89
99
|
|
|
90
100
|
describe file('/tmp/http_request_post.html') do
|
|
91
101
|
it { should be_file }
|
|
92
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
93
|
-
its(:content) { should match(/"love":\s*"sushi"/) }
|
|
102
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
103
|
+
its(:content) { should match(/"love":\s*\[?\s*"sushi"/) }
|
|
94
104
|
end
|
|
95
105
|
|
|
96
106
|
describe file('/tmp/http_request_put.html') do
|
|
97
107
|
it { should be_file }
|
|
98
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
99
|
-
its(:content) { should match(/"love":\s*"sushi"/) }
|
|
108
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
109
|
+
its(:content) { should match(/"love":\s*\[?\s*"sushi"/) }
|
|
100
110
|
end
|
|
101
111
|
|
|
102
112
|
describe file('/tmp/http_request_headers.html') do
|
|
103
113
|
it { should be_file }
|
|
104
|
-
its(:content) { should match(/"User-Agent":\s*"Itamae"/) }
|
|
114
|
+
its(:content) { should match(/"User-Agent":\s*\[?\s*"Itamae"/) }
|
|
105
115
|
end
|
|
106
116
|
|
|
107
117
|
xdescribe file('/tmp/http_request_redirect.html') do
|
|
@@ -274,10 +284,12 @@ end
|
|
|
274
284
|
|
|
275
285
|
describe file('/tmp/file_edit_with_content_change_updates_timestamp') do
|
|
276
286
|
its(:mtime) { should be > DateTime.iso8601("2016-05-02T01:23:45Z") }
|
|
287
|
+
its(:content) { should eq "Hello, Itamae\n" }
|
|
277
288
|
end
|
|
278
289
|
|
|
279
290
|
describe file('/tmp/file_edit_without_content_change_keeping_timestamp') do
|
|
280
291
|
its(:mtime) { should eq(DateTime.iso8601("2016-05-02T12:34:56Z")) }
|
|
292
|
+
its(:content) { should eq "" }
|
|
281
293
|
end
|
|
282
294
|
|
|
283
295
|
describe file('/home/itamae2') do
|
|
@@ -306,10 +318,12 @@ end
|
|
|
306
318
|
|
|
307
319
|
describe file('/tmp/file_with_content_change_updates_timestamp') do
|
|
308
320
|
its(:mtime) { should be > DateTime.iso8601("2016-05-01T01:23:45Z") }
|
|
321
|
+
its(:content) { should eq "Hello, world" }
|
|
309
322
|
end
|
|
310
323
|
|
|
311
324
|
describe file('/tmp/file_without_content_change_keeping_timestamp') do
|
|
312
325
|
its(:mtime) { should eq(DateTime.iso8601("2016-05-01T12:34:56Z")) }
|
|
326
|
+
its(:content) { should eq "Hello, world\n" }
|
|
313
327
|
end
|
|
314
328
|
|
|
315
329
|
describe file('/tmp/subscribed_from_parent') do
|
|
@@ -88,14 +88,14 @@ describe file('/tmp/http_request.html') do
|
|
|
88
88
|
it { should be_file }
|
|
89
89
|
it { should be_owned_by "ordinary_san" }
|
|
90
90
|
it { should be_grouped_into "ordinary_san" }
|
|
91
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
91
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
describe file('/tmp/http_request_root.html') do
|
|
95
95
|
it { should be_file }
|
|
96
96
|
it { should be_owned_by "root" }
|
|
97
97
|
it { should be_grouped_into "root" }
|
|
98
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
98
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
%w[/tmp/http_request_another_ordinary.html /tmp/http_request_another_ordinary_with_root.html].each do |path|
|
|
@@ -103,6 +103,6 @@ end
|
|
|
103
103
|
it { should be_file }
|
|
104
104
|
it { should be_owned_by "itamae" }
|
|
105
105
|
it { should be_grouped_into "itamae" }
|
|
106
|
-
its(:content) { should match(/"from":\s*"itamae"/) }
|
|
106
|
+
its(:content) { should match(/"from":\s*\[?\s*"itamae"/) }
|
|
107
107
|
end
|
|
108
108
|
end
|
|
@@ -39,9 +39,20 @@ user "create itamae2 user with create home directory" do
|
|
|
39
39
|
shell "/bin/sh"
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
group "create itamae_system group" do
|
|
43
|
+
groupname "itamae_system"
|
|
44
|
+
system_group true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
user "create itamae_system user" do
|
|
48
|
+
gid "itamae_system"
|
|
49
|
+
username "itamae_system"
|
|
50
|
+
system_user true
|
|
51
|
+
end
|
|
52
|
+
|
|
42
53
|
######
|
|
43
54
|
|
|
44
|
-
package '
|
|
55
|
+
package 'jq' do
|
|
45
56
|
action :install
|
|
46
57
|
end
|
|
47
58
|
|
|
@@ -55,35 +66,43 @@ package "ruby"
|
|
|
55
66
|
|
|
56
67
|
gem_package 'tzinfo' do
|
|
57
68
|
version '1.1.0'
|
|
69
|
+
cwd '/tmp'
|
|
58
70
|
end
|
|
59
71
|
|
|
60
72
|
gem_package 'tzinfo' do
|
|
61
73
|
version '1.2.2'
|
|
74
|
+
cwd '/tmp'
|
|
62
75
|
end
|
|
63
76
|
|
|
64
77
|
gem_package 'rake' do
|
|
65
78
|
version '11.1.0'
|
|
79
|
+
cwd '/tmp'
|
|
66
80
|
end
|
|
67
81
|
|
|
68
82
|
gem_package 'rake' do
|
|
69
83
|
version '11.2.2'
|
|
84
|
+
cwd '/tmp'
|
|
70
85
|
end
|
|
71
86
|
|
|
72
87
|
gem_package 'rake' do
|
|
73
88
|
action :uninstall
|
|
74
89
|
version '11.2.2'
|
|
90
|
+
cwd '/tmp'
|
|
75
91
|
end
|
|
76
92
|
|
|
77
93
|
gem_package 'test-unit' do
|
|
78
94
|
version '2.5.5'
|
|
95
|
+
cwd '/tmp'
|
|
79
96
|
end
|
|
80
97
|
|
|
81
98
|
gem_package 'test-unit' do
|
|
82
99
|
version '2.4.9'
|
|
100
|
+
cwd '/tmp'
|
|
83
101
|
end
|
|
84
102
|
|
|
85
103
|
gem_package 'test-unit' do
|
|
86
104
|
action :uninstall
|
|
105
|
+
cwd '/tmp'
|
|
87
106
|
end
|
|
88
107
|
|
|
89
108
|
######
|
|
@@ -184,35 +203,39 @@ end
|
|
|
184
203
|
|
|
185
204
|
######
|
|
186
205
|
|
|
206
|
+
httpbin_url = ENV.fetch("HTTPBIN_URL") { "http://127.0.0.1:#{ENV.fetch('HTTPBIN_HOST_PORT', '8080')}" }
|
|
207
|
+
|
|
187
208
|
http_request "/tmp/http_request.html" do
|
|
188
|
-
url "
|
|
209
|
+
url "#{httpbin_url}/get?from=itamae"
|
|
189
210
|
end
|
|
190
211
|
|
|
191
212
|
http_request "/tmp/http_request_delete.html" do
|
|
192
213
|
action :delete
|
|
193
|
-
url "
|
|
214
|
+
url "#{httpbin_url}/delete?from=itamae"
|
|
194
215
|
end
|
|
195
216
|
|
|
196
217
|
http_request "/tmp/http_request_post.html" do
|
|
197
218
|
action :post
|
|
219
|
+
headers "Content-Type" => "application/x-www-form-urlencoded"
|
|
198
220
|
message "love=sushi"
|
|
199
|
-
url "
|
|
221
|
+
url "#{httpbin_url}/post?from=itamae"
|
|
200
222
|
end
|
|
201
223
|
|
|
202
224
|
http_request "/tmp/http_request_put.html" do
|
|
203
225
|
action :put
|
|
226
|
+
headers "Content-Type" => "application/x-www-form-urlencoded"
|
|
204
227
|
message "love=sushi"
|
|
205
|
-
url "
|
|
228
|
+
url "#{httpbin_url}/put?from=itamae"
|
|
206
229
|
end
|
|
207
230
|
|
|
208
231
|
http_request "/tmp/http_request_headers.html" do
|
|
209
232
|
headers "User-Agent" => "Itamae"
|
|
210
|
-
url "
|
|
233
|
+
url "#{httpbin_url}/get"
|
|
211
234
|
end
|
|
212
235
|
|
|
213
236
|
# http_request "/tmp/http_request_redirect.html" do
|
|
214
237
|
# redirect_limit 1
|
|
215
|
-
# url "
|
|
238
|
+
# url "#{httpbin_url}/redirect-to?url=#{httpbin_url}/get%3Ffrom%3Ditamae"
|
|
216
239
|
# end
|
|
217
240
|
|
|
218
241
|
link "/tmp-link" do
|
|
@@ -83,27 +83,29 @@ end
|
|
|
83
83
|
|
|
84
84
|
###
|
|
85
85
|
|
|
86
|
+
httpbin_url = ENV.fetch("HTTPBIN_URL") { "http://127.0.0.1:#{ENV.fetch('HTTPBIN_HOST_PORT', '8080')}" }
|
|
87
|
+
|
|
86
88
|
http_request "/tmp/http_request.html" do
|
|
87
|
-
url "
|
|
89
|
+
url "#{httpbin_url}/get?from=itamae"
|
|
88
90
|
end
|
|
89
91
|
|
|
90
92
|
http_request "/tmp/http_request_root.html" do
|
|
91
93
|
user 'root'
|
|
92
94
|
owner 'root'
|
|
93
95
|
group 'root'
|
|
94
|
-
url "
|
|
96
|
+
url "#{httpbin_url}/get?from=itamae"
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
http_request "/tmp/http_request_another_ordinary.html" do
|
|
98
100
|
user 'itamae'
|
|
99
101
|
owner 'itamae'
|
|
100
102
|
group 'itamae'
|
|
101
|
-
url "
|
|
103
|
+
url "#{httpbin_url}/get?from=itamae"
|
|
102
104
|
end
|
|
103
105
|
|
|
104
106
|
http_request "/tmp/http_request_another_ordinary_with_root.html" do
|
|
105
107
|
user 'root'
|
|
106
108
|
owner 'itamae'
|
|
107
109
|
group 'itamae'
|
|
108
|
-
url "
|
|
110
|
+
url "#{httpbin_url}/get?from=itamae"
|
|
109
111
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Manage a local mccutchen/go-httpbin container for the integration tests.
|
|
2
|
+
#
|
|
3
|
+
# The public httpbin.org service is flaky and, under the CI matrix, receives
|
|
4
|
+
# so many simultaneous requests that it returns 500s. Running an httpbin-compatible
|
|
5
|
+
# server locally removes that external dependency.
|
|
6
|
+
#
|
|
7
|
+
# The `http_request` resource issues the HTTP request from the itamae process
|
|
8
|
+
# itself (`Net::HTTP`), so the reachable URL differs per backend:
|
|
9
|
+
# - docker backend: itamae runs on the host -> host_url (published port)
|
|
10
|
+
# - local backend: itamae runs in a container -> NETWORK_URL (shared network)
|
|
11
|
+
# The container therefore exposes both a published loopback port and a shared network.
|
|
12
|
+
module HttpbinServer
|
|
13
|
+
IMAGE = 'ghcr.io/mccutchen/go-httpbin:2.24.0'
|
|
14
|
+
NETWORK = 'itamae-test'
|
|
15
|
+
CONTAINER = 'httpbin'
|
|
16
|
+
PORT = 8080 # container port; also the port in NETWORK_URL
|
|
17
|
+
NETWORK_URL = "http://#{CONTAINER}:#{PORT}".freeze # reachable from a container on NETWORK
|
|
18
|
+
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
# Host port to publish go-httpbin on. Overridable so local runs can avoid a
|
|
22
|
+
# port already in use on the host (CI runners always have the default free).
|
|
23
|
+
def host_port
|
|
24
|
+
ENV.fetch('HTTPBIN_HOST_PORT', PORT.to_s)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# URL reachable from the itamae host (docker backend). Kept in sync with the
|
|
28
|
+
# recipe default in spec/integration/recipes/*.rb.
|
|
29
|
+
def host_url
|
|
30
|
+
"http://127.0.0.1:#{host_port}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def start
|
|
34
|
+
create_network
|
|
35
|
+
remove_container # drop any stale container from a previous run
|
|
36
|
+
run! 'docker', 'run', '-d', '--name', CONTAINER,
|
|
37
|
+
'--network', NETWORK,
|
|
38
|
+
'-p', "127.0.0.1:#{host_port}:#{PORT}",
|
|
39
|
+
IMAGE
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def stop
|
|
43
|
+
remove_container
|
|
44
|
+
quiet 'docker', 'network', 'rm', NETWORK
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_network
|
|
48
|
+
return if system('docker', 'network', 'inspect', NETWORK, out: File::NULL, err: File::NULL)
|
|
49
|
+
run! 'docker', 'network', 'create', NETWORK
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def remove_container
|
|
53
|
+
quiet 'docker', 'rm', '-f', CONTAINER
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def run!(*cmd)
|
|
57
|
+
system(*cmd) or raise "command failed: #{cmd.join(' ')}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def quiet(*cmd)
|
|
61
|
+
system(*cmd, out: File::NULL, err: File::NULL)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -10,22 +10,27 @@ namespace 'spec:integration:local' do
|
|
|
10
10
|
next
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
HttpbinServer.start
|
|
14
|
+
ENV['HTTPBIN_URL'] = HttpbinServer::NETWORK_URL
|
|
15
|
+
begin
|
|
16
|
+
IntegrationLocalSpecRunner.new(
|
|
15
17
|
[
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
[
|
|
19
|
+
"spec/integration/recipes/default.rb",
|
|
20
|
+
"spec/integration/recipes/default2.rb",
|
|
21
|
+
"spec/integration/recipes/redefine.rb",
|
|
22
|
+
"spec/integration/recipes/local.rb",
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
"--dry-run",
|
|
26
|
+
"spec/integration/recipes/dry_run.rb",
|
|
27
|
+
],
|
|
20
28
|
],
|
|
21
|
-
[
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
['spec/integration/default_spec.rb']
|
|
27
|
-
).run
|
|
28
|
-
|
|
29
|
+
['spec/integration/default_spec.rb']
|
|
30
|
+
).run
|
|
31
|
+
ensure
|
|
32
|
+
HttpbinServer.stop
|
|
33
|
+
end
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
desc 'Run integration test for ordinary user with `itamae local`'
|
|
@@ -36,23 +41,29 @@ namespace 'spec:integration:local' do
|
|
|
36
41
|
next
|
|
37
42
|
end
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
HttpbinServer.start
|
|
45
|
+
ENV['HTTPBIN_URL'] = HttpbinServer::NETWORK_URL
|
|
46
|
+
begin
|
|
47
|
+
runner = IntegrationLocalSpecRunner.new(
|
|
41
48
|
[
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
[
|
|
50
|
+
"--dry-run",
|
|
51
|
+
"spec/integration/recipes/ordinary_user.rb",
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
"spec/integration/recipes/ordinary_user.rb"
|
|
55
|
+
],
|
|
44
56
|
],
|
|
45
|
-
[
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
runner.run
|
|
57
|
+
['spec/integration/ordinary_user_spec.rb'],
|
|
58
|
+
user: 'ordinary_san'
|
|
59
|
+
)
|
|
60
|
+
runner.docker_exec 'useradd', 'ordinary_san', '-p', '*'
|
|
61
|
+
runner.docker_exec 'useradd', 'itamae', '-p', '*', '--create-home'
|
|
62
|
+
runner.docker_exec 'sh', '-c', 'echo "ordinary_san ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers'
|
|
63
|
+
runner.run
|
|
64
|
+
ensure
|
|
65
|
+
HttpbinServer.stop
|
|
66
|
+
end
|
|
56
67
|
end
|
|
57
68
|
end
|
|
58
69
|
|
|
@@ -78,11 +89,14 @@ class IntegrationLocalSpecRunner
|
|
|
78
89
|
|
|
79
90
|
def docker_run
|
|
80
91
|
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'
|
|
92
|
+
sh 'docker', 'run', '--env', 'HTTPBIN_URL', '--network', HttpbinServer::NETWORK, '--privileged', '-d', '--name', CONTAINER_NAME, '-v', "#{mount_dir}:/itamae", "ruby:#{@ruby_version}", 'sleep', '1d'
|
|
82
93
|
end
|
|
83
94
|
|
|
84
95
|
def prepare
|
|
85
|
-
|
|
96
|
+
# Install the same version of bundler into the Docker container as is installed locally
|
|
97
|
+
current_bundler_version = /([0-9.]+)/.match(`bundle -v`).captures[0]
|
|
98
|
+
docker_exec 'gem', 'install', 'bundler', '-v', current_bundler_version
|
|
99
|
+
|
|
86
100
|
docker_exec 'bundle', 'install', options: %w[--workdir /itamae]
|
|
87
101
|
docker_exec 'apt-get', 'update', '-y'
|
|
88
102
|
docker_exec 'apt-get', 'install', 'locales', 'sudo', '-y'
|
|
@@ -112,6 +126,6 @@ class IntegrationLocalSpecRunner
|
|
|
112
126
|
end
|
|
113
127
|
|
|
114
128
|
def docker_exec(*cmd, options: [])
|
|
115
|
-
sh 'docker', 'exec', '--env', 'LANG=en_US.utf8', *options, CONTAINER_NAME, *cmd
|
|
129
|
+
sh 'docker', 'exec', '--env', 'LANG=en_US.utf8', '--env', 'HTTPBIN_URL', *options, CONTAINER_NAME, *cmd
|
|
116
130
|
end
|
|
117
131
|
end
|
metadata
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: itamae
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryota Arai
|
|
8
8
|
- Yusuke Nakamura
|
|
9
9
|
- sue445
|
|
10
|
-
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
|
-
date:
|
|
12
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
14
13
|
dependencies:
|
|
15
14
|
- !ruby/object:Gem::Dependency
|
|
16
15
|
name: thor
|
|
@@ -32,7 +31,7 @@ dependencies:
|
|
|
32
31
|
requirements:
|
|
33
32
|
- - ">="
|
|
34
33
|
- !ruby/object:Gem::Version
|
|
35
|
-
version: 2.
|
|
34
|
+
version: 2.81.0
|
|
36
35
|
- - "<"
|
|
37
36
|
- !ruby/object:Gem::Version
|
|
38
37
|
version: 3.0.0
|
|
@@ -42,7 +41,7 @@ dependencies:
|
|
|
42
41
|
requirements:
|
|
43
42
|
- - ">="
|
|
44
43
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: 2.
|
|
44
|
+
version: 2.81.0
|
|
46
45
|
- - "<"
|
|
47
46
|
- !ruby/object:Gem::Version
|
|
48
47
|
version: 3.0.0
|
|
@@ -136,14 +135,14 @@ dependencies:
|
|
|
136
135
|
requirements:
|
|
137
136
|
- - "~>"
|
|
138
137
|
- !ruby/object:Gem::Version
|
|
139
|
-
version: '2.
|
|
138
|
+
version: '2.43'
|
|
140
139
|
type: :development
|
|
141
140
|
prerelease: false
|
|
142
141
|
version_requirements: !ruby/object:Gem::Requirement
|
|
143
142
|
requirements:
|
|
144
143
|
- - "~>"
|
|
145
144
|
- !ruby/object:Gem::Version
|
|
146
|
-
version: '2.
|
|
145
|
+
version: '2.43'
|
|
147
146
|
- !ruby/object:Gem::Dependency
|
|
148
147
|
name: pry-byebug
|
|
149
148
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -200,7 +199,6 @@ dependencies:
|
|
|
200
199
|
- - ">="
|
|
201
200
|
- !ruby/object:Gem::Version
|
|
202
201
|
version: '0'
|
|
203
|
-
description:
|
|
204
202
|
email:
|
|
205
203
|
- ryota.arai@gmail.com
|
|
206
204
|
- yusuke1994525@gmail.com
|
|
@@ -210,7 +208,11 @@ executables:
|
|
|
210
208
|
extensions: []
|
|
211
209
|
extra_rdoc_files: []
|
|
212
210
|
files:
|
|
211
|
+
- ".github/dependabot.yml"
|
|
212
|
+
- ".github/workflows/docker-daemon.json"
|
|
213
|
+
- ".github/workflows/release.yml"
|
|
213
214
|
- ".github/workflows/test.yml"
|
|
215
|
+
- ".github/workflows/test_main.yml"
|
|
214
216
|
- ".gitignore"
|
|
215
217
|
- ".rspec"
|
|
216
218
|
- CHANGELOG.md
|
|
@@ -308,6 +310,7 @@ files:
|
|
|
308
310
|
- spec/unit/lib/itamae/resource_spec.rb
|
|
309
311
|
- spec/unit/lib/itamae/runner_spec.rb
|
|
310
312
|
- spec/unit/spec_helper.rb
|
|
313
|
+
- tasks/httpbin_server.rb
|
|
311
314
|
- tasks/integration_local_spec.rb
|
|
312
315
|
homepage: https://itamae.kitchen/
|
|
313
316
|
licenses:
|
|
@@ -317,7 +320,6 @@ metadata:
|
|
|
317
320
|
source_code_uri: https://github.com/itamae-kitchen/itamae
|
|
318
321
|
changelog_uri: https://github.com/itamae-kitchen/itamae/blob/master/CHANGELOG.md
|
|
319
322
|
rubygems_mfa_required: 'true'
|
|
320
|
-
post_install_message:
|
|
321
323
|
rdoc_options: []
|
|
322
324
|
require_paths:
|
|
323
325
|
- lib
|
|
@@ -332,8 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
332
334
|
- !ruby/object:Gem::Version
|
|
333
335
|
version: '0'
|
|
334
336
|
requirements: []
|
|
335
|
-
rubygems_version:
|
|
336
|
-
signing_key:
|
|
337
|
+
rubygems_version: 4.0.16
|
|
337
338
|
specification_version: 4
|
|
338
339
|
summary: Simple Configuration Management Tool
|
|
339
340
|
test_files:
|