r10k 3.4.1 → 3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +4 -1
- data/.github/workflows/docker.yml +25 -1
- data/.github/workflows/rspec_tests.yml +81 -0
- data/.travis.yml +19 -8
- data/CHANGELOG.mkd +46 -6
- data/Gemfile +1 -1
- data/README.mkd +13 -4
- data/azure-pipelines.yml +4 -2
- data/doc/dynamic-environments/configuration.mkd +49 -3
- data/doc/faq.mkd +6 -1
- data/doc/puppetfile.mkd +2 -0
- data/docker/Makefile +19 -3
- data/docker/r10k/Dockerfile +22 -8
- data/docker/r10k/release.Dockerfile +23 -4
- data/integration/tests/git_source/git_source_repeated_remote.rb +68 -0
- data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +1 -1
- data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +1 -1
- data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +1 -1
- data/lib/r10k/action/deploy/environment.rb +6 -1
- data/lib/r10k/action/deploy/module.rb +2 -1
- data/lib/r10k/action/runner.rb +5 -4
- data/lib/r10k/cli/deploy.rb +1 -0
- data/lib/r10k/environment/base.rb +1 -1
- data/lib/r10k/forge/module_release.rb +2 -2
- data/lib/r10k/git/cache.rb +12 -4
- data/lib/r10k/git/stateful_repository.rb +4 -0
- data/lib/r10k/initializers.rb +1 -0
- data/lib/r10k/module/base.rb +8 -0
- data/lib/r10k/module/git.rb +4 -0
- data/lib/r10k/puppetfile.rb +26 -6
- data/lib/r10k/settings.rb +12 -1
- data/lib/r10k/source.rb +1 -0
- data/lib/r10k/source/exec.rb +51 -0
- data/lib/r10k/source/git.rb +22 -2
- data/lib/r10k/source/hash.rb +32 -8
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +33 -10
- data/spec/shared-examples/subprocess-runner.rb +11 -5
- data/spec/unit/action/deploy/environment_spec.rb +9 -0
- data/spec/unit/action/deploy/module_spec.rb +15 -2
- data/spec/unit/action/puppetfile/install_spec.rb +4 -1
- data/spec/unit/action/runner_spec.rb +2 -2
- data/spec/unit/forge/module_release_spec.rb +14 -10
- data/spec/unit/git/cache_spec.rb +10 -0
- data/spec/unit/git/rugged/credentials_spec.rb +1 -1
- data/spec/unit/git_spec.rb +3 -3
- data/spec/unit/puppetfile_spec.rb +67 -2
- data/spec/unit/settings_spec.rb +12 -0
- data/spec/unit/source/exec_spec.rb +81 -0
- data/spec/unit/source/git_spec.rb +49 -1
- data/spec/unit/source/hash_spec.rb +54 -0
- data/spec/unit/source/yaml_spec.rb +42 -0
- metadata +8 -2
data/docker/Makefile
CHANGED
@@ -1,17 +1,27 @@
|
|
1
1
|
PUPPERWARE_ANALYTICS_STREAM ?= dev
|
2
2
|
NAMESPACE ?= puppet
|
3
|
-
git_describe = $(shell git describe)
|
3
|
+
git_describe = $(shell git describe --tags)
|
4
4
|
vcs_ref := $(shell git rev-parse HEAD)
|
5
5
|
build_date := $(shell date -u +%FT%T)
|
6
6
|
hadolint_available := $(shell hadolint --help > /dev/null 2>&1; echo $$?)
|
7
|
-
hadolint_command := hadolint
|
7
|
+
hadolint_command := hadolint
|
8
8
|
hadolint_container := hadolint/hadolint:latest
|
9
|
+
alpine_version := 3.9
|
9
10
|
export BUNDLE_PATH = $(PWD)/.bundle/gems
|
10
11
|
export BUNDLE_BIN = $(PWD)/.bundle/bin
|
11
12
|
export GEMFILE = $(PWD)/Gemfile
|
13
|
+
export DOCKER_BUILDKIT = 1
|
12
14
|
|
13
15
|
ifeq ($(IS_RELEASE),true)
|
14
16
|
VERSION ?= $(shell echo $(git_describe) | sed 's/-.*//')
|
17
|
+
PUBLISHED_VERSION ?= $(shell curl --silent 'https://rubygems.org/api/v1/gems/r10k.json' | jq '."version"' | tr -d '"')
|
18
|
+
CONTAINER_EXISTS = $(shell DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $(NAMESPACE)/r10k:$(VERSION) > /dev/null 2>&1; echo $$?)
|
19
|
+
ifeq ($(CONTAINER_EXISTS),0)
|
20
|
+
SKIP_BUILD ?= true
|
21
|
+
else ifneq ($(VERSION),$(PUBLISHED_VERSION))
|
22
|
+
SKIP_BUILD ?= true
|
23
|
+
endif
|
24
|
+
|
15
25
|
LATEST_VERSION ?= latest
|
16
26
|
dockerfile := release.Dockerfile
|
17
27
|
dockerfile_context := r10k
|
@@ -25,6 +35,10 @@ endif
|
|
25
35
|
prep:
|
26
36
|
@git fetch --unshallow 2> /dev/null ||:
|
27
37
|
@git fetch origin 'refs/tags/*:refs/tags/*'
|
38
|
+
ifeq ($(SKIP_BUILD),true)
|
39
|
+
@echo "SKIP_BUILD is true, exiting with 1"
|
40
|
+
@exit 1
|
41
|
+
endif
|
28
42
|
|
29
43
|
lint:
|
30
44
|
ifeq ($(hadolint_available),0)
|
@@ -35,8 +49,10 @@ else
|
|
35
49
|
endif
|
36
50
|
|
37
51
|
build: prep
|
52
|
+
docker pull alpine:$(alpine_version)
|
38
53
|
docker build \
|
39
|
-
|
54
|
+
${DOCKER_BUILD_FLAGS} \
|
55
|
+
--build-arg alpine_version=$(alpine_version) \
|
40
56
|
--build-arg vcs_ref=$(vcs_ref) \
|
41
57
|
--build-arg build_date=$(build_date) \
|
42
58
|
--build-arg version=$(VERSION) \
|
data/docker/r10k/Dockerfile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
1
|
+
ARG alpine_version=3.9
|
2
|
+
FROM alpine:${alpine_version} as build
|
2
3
|
|
4
|
+
# hadolint ignore=DL3018
|
3
5
|
RUN apk add --no-cache ruby git && \
|
4
6
|
mkdir /workspace
|
5
7
|
WORKDIR /workspace
|
@@ -7,7 +9,7 @@ COPY . /workspace
|
|
7
9
|
RUN gem build r10k.gemspec && \
|
8
10
|
mv r10k*.gem r10k.gem
|
9
11
|
|
10
|
-
FROM alpine
|
12
|
+
FROM alpine:${alpine_version}
|
11
13
|
|
12
14
|
ARG vcs_ref
|
13
15
|
ARG build_date
|
@@ -15,6 +17,11 @@ ARG version="3.1.0"
|
|
15
17
|
# Used by entrypoint to submit metrics to Google Analytics.
|
16
18
|
# Published images should use "production" for this build_arg.
|
17
19
|
ARG pupperware_analytics_stream="dev"
|
20
|
+
# required to schedule runs of "r10k" in K8s
|
21
|
+
ARG supercronic_version="0.1.9"
|
22
|
+
ARG supercronic_sha1sum="5ddf8ea26b56d4a7ff6faecdd8966610d5cb9d85"
|
23
|
+
ARG supercronic="supercronic-linux-amd64"
|
24
|
+
ARG supercronic_url="https://github.com/aptible/supercronic/releases/download/v$supercronic_version/$supercronic"
|
18
25
|
|
19
26
|
LABEL org.label-schema.maintainer="Puppet Release Team <release@puppet.com>" \
|
20
27
|
org.label-schema.vendor="Puppet" \
|
@@ -31,7 +38,7 @@ COPY docker/r10k/docker-entrypoint.d /docker-entrypoint.d
|
|
31
38
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
32
39
|
CMD ["help"]
|
33
40
|
|
34
|
-
#
|
41
|
+
# dynamic LABELs and ENV vars placed lower for the sake of Docker layer caching
|
35
42
|
ENV PUPPERWARE_ANALYTICS_STREAM="$pupperware_analytics_stream"
|
36
43
|
|
37
44
|
LABEL org.label-schema.version="$version" \
|
@@ -39,14 +46,21 @@ LABEL org.label-schema.version="$version" \
|
|
39
46
|
org.label-schema.build-date="$build_date"
|
40
47
|
|
41
48
|
COPY --from=build /workspace/r10k.gem /
|
42
|
-
|
49
|
+
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
|
50
|
+
# ignore apk and gem pinning
|
51
|
+
# hadolint ignore=DL3018,DL3028
|
52
|
+
RUN chmod a+x /adduser.sh /docker-entrypoint.sh && \
|
43
53
|
# Add a puppet user to run r10k as for consistency with puppetserver
|
44
54
|
/adduser.sh && \
|
45
|
-
chmod +x /docker-entrypoint.sh && \
|
46
55
|
chown -R puppet: /docker-entrypoint.d /docker-entrypoint.sh && \
|
47
|
-
apk add --no-cache ruby openssh-client git ruby-rugged curl ruby-
|
48
|
-
gem install --no-doc /r10k.gem
|
49
|
-
rm -f /r10k.gem
|
56
|
+
apk add --no-cache ruby openssh-client git ruby-rugged curl ruby-json ruby-etc && \
|
57
|
+
gem install --no-doc /r10k.gem && \
|
58
|
+
rm -f /r10k.gem && \
|
59
|
+
curl --fail --silent --show-error --location --remote-name "$supercronic_url" && \
|
60
|
+
echo "${supercronic_sha1sum} ${supercronic}" | sha1sum -c - && \
|
61
|
+
chmod +x "$supercronic" && \
|
62
|
+
mv "$supercronic" "/usr/local/bin/${supercronic}" && \
|
63
|
+
ln -s "/usr/local/bin/${supercronic}" /usr/local/bin/supercronic
|
50
64
|
|
51
65
|
USER puppet
|
52
66
|
WORKDIR /home/puppet
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
ARG alpine_version=3.9
|
2
|
+
FROM alpine:${alpine_version}
|
2
3
|
|
3
4
|
ARG vcs_ref
|
4
5
|
ARG build_date
|
@@ -6,6 +7,11 @@ ARG version="3.1.0"
|
|
6
7
|
# Used by entrypoint to submit metrics to Google Analytics.
|
7
8
|
# Published images should use "production" for this build_arg.
|
8
9
|
ARG pupperware_analytics_stream="dev"
|
10
|
+
# required to schedule runs of "r10k" in K8s
|
11
|
+
ARG supercronic_version="0.1.9"
|
12
|
+
ARG supercronic_sha1sum="5ddf8ea26b56d4a7ff6faecdd8966610d5cb9d85"
|
13
|
+
ARG supercronic="supercronic-linux-amd64"
|
14
|
+
ARG supercronic_url="https://github.com/aptible/supercronic/releases/download/v$supercronic_version/$supercronic"
|
9
15
|
|
10
16
|
LABEL org.label-schema.maintainer="Puppet Release Team <release@puppet.com>" \
|
11
17
|
org.label-schema.vendor="Puppet" \
|
@@ -16,7 +22,7 @@ LABEL org.label-schema.maintainer="Puppet Release Team <release@puppet.com>" \
|
|
16
22
|
org.label-schema.schema-version="1.0" \
|
17
23
|
org.label-schema.dockerfile="/release.Dockerfile"
|
18
24
|
|
19
|
-
COPY docker-entrypoint.sh /
|
25
|
+
COPY adduser.sh docker-entrypoint.sh /
|
20
26
|
COPY docker-entrypoint.d /docker-entrypoint.d
|
21
27
|
|
22
28
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
@@ -29,8 +35,21 @@ LABEL org.label-schema.version="$version" \
|
|
29
35
|
org.label-schema.vcs-ref="$vcs_ref" \
|
30
36
|
org.label-schema.build-date="$build_date"
|
31
37
|
|
32
|
-
|
38
|
+
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
|
39
|
+
# ignore apk and gem pinning
|
40
|
+
# hadolint ignore=DL3018,DL3028
|
41
|
+
RUN chmod a+x /adduser.sh /docker-entrypoint.sh && \
|
42
|
+
/adduser.sh && \
|
43
|
+
chown -R puppet: /docker-entrypoint.d /docker-entrypoint.sh && \
|
33
44
|
apk add --no-cache ruby openssh-client git ruby-rugged curl ruby-dev make gcc musl-dev && \
|
34
|
-
gem install --no-doc r10k:"$version" json etc
|
45
|
+
gem install --no-doc r10k:"$version" json etc && \
|
46
|
+
curl --fail --silent --show-error --location --remote-name "$supercronic_url" && \
|
47
|
+
echo "${supercronic_sha1sum} ${supercronic}" | sha1sum -c - && \
|
48
|
+
chmod +x "$supercronic" && \
|
49
|
+
mv "$supercronic" "/usr/local/bin/${supercronic}" && \
|
50
|
+
ln -s "/usr/local/bin/${supercronic}" /usr/local/bin/supercronic
|
51
|
+
|
52
|
+
USER puppet
|
53
|
+
WORKDIR /home/puppet
|
35
54
|
|
36
55
|
COPY release.Dockerfile /
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'git_utils'
|
2
|
+
require 'r10k_utils'
|
3
|
+
require 'master_manipulator'
|
4
|
+
test_name 'Verify the same remote can be used in more than one object'
|
5
|
+
|
6
|
+
env_path = on(master, puppet('config print environmentpath')).stdout.rstrip
|
7
|
+
r10k_fqp = get_r10k_fqp(master)
|
8
|
+
git_environments_path = '/root/environments'
|
9
|
+
git_repo_path = '/git_repos'
|
10
|
+
git_repo_name = 'environments'
|
11
|
+
git_control_remote = File.join(git_repo_path, "#{git_repo_name}.git")
|
12
|
+
code_dir = "#{env_path}/production"
|
13
|
+
|
14
|
+
last_commit = git_last_commit(master, git_environments_path)
|
15
|
+
git_provider = ENV['GIT_PROVIDER']
|
16
|
+
r10k_config_path = get_r10k_config_file_path(master)
|
17
|
+
r10k_config_bak_path = "#{r10k_config_path}.bak"
|
18
|
+
#In-line files
|
19
|
+
r10k_conf = <<-CONF
|
20
|
+
cachedir: '/var/cache/r10k'
|
21
|
+
git:
|
22
|
+
provider: '#{git_provider}'
|
23
|
+
sources:
|
24
|
+
control:
|
25
|
+
basedir: "#{env_path}"
|
26
|
+
remote: "#{git_control_remote}"
|
27
|
+
CONF
|
28
|
+
|
29
|
+
# Install the same module in two different places
|
30
|
+
puppetfile = <<-EOS
|
31
|
+
mod 'prod_apache',
|
32
|
+
:git => 'git://github.com/puppetlabs/puppetlabs-apache.git',
|
33
|
+
:branch => 'master'
|
34
|
+
|
35
|
+
mod 'test_apache',
|
36
|
+
:git => 'git://github.com/puppetlabs/puppetlabs-apache.git',
|
37
|
+
:branch => 'master'
|
38
|
+
EOS
|
39
|
+
|
40
|
+
teardown do
|
41
|
+
step 'Restore Original "r10k" Config'
|
42
|
+
on(master, "mv #{r10k_config_bak_path} #{r10k_config_path}")
|
43
|
+
|
44
|
+
clean_up_r10k(master, last_commit, git_environments_path)
|
45
|
+
end
|
46
|
+
|
47
|
+
step 'Stub the forge'
|
48
|
+
stub_forge_on(master)
|
49
|
+
|
50
|
+
step 'Backup Current "r10k" Config'
|
51
|
+
on(master, "mv #{r10k_config_path} #{r10k_config_bak_path}")
|
52
|
+
|
53
|
+
step 'Update the "r10k" Config'
|
54
|
+
create_remote_file(master, r10k_config_path, r10k_conf)
|
55
|
+
|
56
|
+
step 'Ask r10k to deploy'
|
57
|
+
on(master, "#{r10k_fqp} deploy environment -p")
|
58
|
+
|
59
|
+
step 'Add puppetfile with repeated remote'
|
60
|
+
create_remote_file(master, "#{git_environments_path}/Puppetfile", puppetfile)
|
61
|
+
git_add_commit_push(master, 'production', 'add Puppetfile', git_environments_path)
|
62
|
+
|
63
|
+
step 'Deploy r10k'
|
64
|
+
on(master, "#{r10k_fqp} deploy environment -p")
|
65
|
+
|
66
|
+
step 'Verify module was installed in both places'
|
67
|
+
on(master, "test -d #{code_dir}/modules/prod_apache")
|
68
|
+
on(master, "test -d #{code_dir}/modules/test_apache")
|
@@ -24,7 +24,7 @@ stage_env_notify_message = 'This is a different message'
|
|
24
24
|
stage_env_notify_message_regex = /#{stage_env_notify_message}/
|
25
25
|
|
26
26
|
#Verification for "test" Environment
|
27
|
-
test_env_error_message_regex = /Error:.*Could not
|
27
|
+
test_env_error_message_regex = /Error:.*Could not.*environment '?test'?/
|
28
28
|
|
29
29
|
#Verification for "temp" Environment
|
30
30
|
test_env_notify_message_regex = /I am in the temp environment/
|
@@ -15,7 +15,7 @@ initial_env_names = ['production', 'stage']
|
|
15
15
|
|
16
16
|
#Verification
|
17
17
|
notify_message_regex = /I am in the production environment/
|
18
|
-
stage_env_error_message_regex = /Error:.*Could not
|
18
|
+
stage_env_error_message_regex = /Error:.*Could not.*environment '?stage'?/
|
19
19
|
|
20
20
|
#Manifest
|
21
21
|
site_pp_path = File.join(git_environments_path, 'manifests', 'site.pp')
|
@@ -22,7 +22,7 @@ site_pp = create_site_pp(master_certname, ' include helloworld')
|
|
22
22
|
notify_message_prod_env_regex = /I am in the production environment/
|
23
23
|
notify_message_test_env_regex = /I am in the test environment/
|
24
24
|
removal_message_test_env_regex = /Removing unmanaged path.*test/
|
25
|
-
error_message_regex = /Could not retrieve catalog from remote server/
|
25
|
+
error_message_regex = /Could not retrieve (catalog from remote server|information from environment test)/
|
26
26
|
|
27
27
|
#Teardown
|
28
28
|
teardown do
|
@@ -157,7 +157,10 @@ module R10K
|
|
157
157
|
logger.debug("Unable to get environment module deploy data for .r10k-deploy.json at #{environment.path}")
|
158
158
|
end
|
159
159
|
|
160
|
-
|
160
|
+
# make this file write as atomic as possible in pure ruby
|
161
|
+
final = "#{environment.path}/.r10k-deploy.json"
|
162
|
+
staging = "#{environment.path}/.r10k-deploy.json~"
|
163
|
+
File.open(staging, 'w') do |f|
|
161
164
|
deploy_info = environment.info.merge({
|
162
165
|
:started_at => started_at,
|
163
166
|
:finished_at => Time.new,
|
@@ -167,6 +170,7 @@ module R10K
|
|
167
170
|
|
168
171
|
f.puts(JSON.pretty_generate(deploy_info))
|
169
172
|
end
|
173
|
+
FileUtils.mv(staging, final)
|
170
174
|
end
|
171
175
|
|
172
176
|
def undeployable_environment_names(environments, expected_names)
|
@@ -184,6 +188,7 @@ module R10K
|
|
184
188
|
'no-force': :self,
|
185
189
|
'generate-types': :self,
|
186
190
|
'puppet-path': :self,
|
191
|
+
'puppet-conf': :self,
|
187
192
|
'default-branch-override': :self)
|
188
193
|
end
|
189
194
|
end
|
data/lib/r10k/action/runner.rb
CHANGED
@@ -43,10 +43,11 @@ module R10K
|
|
43
43
|
config_settings = settings_from_config(@opts[:config])
|
44
44
|
|
45
45
|
overrides = {}
|
46
|
-
overrides[:cachedir] = @opts[:cachedir]
|
47
|
-
overrides[:deploy] = {} if
|
48
|
-
overrides[:deploy][:puppet_path] = @opts[:'puppet-path']
|
49
|
-
overrides[:deploy][:
|
46
|
+
overrides[:cachedir] = @opts[:cachedir] if @opts.key?(:cachedir)
|
47
|
+
overrides[:deploy] = {} if @opts.key?(:'puppet-path') || @opts.key?(:'generate-types')
|
48
|
+
overrides[:deploy][:puppet_path] = @opts[:'puppet-path'] if @opts.key?(:'puppet-path')
|
49
|
+
overrides[:deploy][:puppet_conf] = @opts[:'puppet-conf'] unless @opts[:'puppet-conf'].nil?
|
50
|
+
overrides[:deploy][:generate_types] = @opts[:'generate-types'] if @opts.key?(:'generate-types')
|
50
51
|
|
51
52
|
with_overrides = config_settings.merge(overrides) do |key, oldval, newval|
|
52
53
|
newval = oldval.merge(newval) if oldval.is_a? Hash
|
data/lib/r10k/cli/deploy.rb
CHANGED
@@ -137,7 +137,7 @@ class R10K::Environment::Base
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def generate_types!
|
140
|
-
argv = [R10K::Settings.puppet_path, 'generate', 'types', '--environment', dirname, '--environmentpath', basedir]
|
140
|
+
argv = [R10K::Settings.puppet_path, 'generate', 'types', '--environment', dirname, '--environmentpath', basedir, '--config', R10K::Settings.puppet_conf]
|
141
141
|
subproc = R10K::Util::Subprocess.new(argv)
|
142
142
|
subproc.raise_on_fail = true
|
143
143
|
subproc.logger = logger
|
@@ -212,14 +212,14 @@ module R10K
|
|
212
212
|
|
213
213
|
# Remove the temporary directory used for unpacking the module.
|
214
214
|
def cleanup_unpack_path
|
215
|
-
if unpack_path.exist?
|
215
|
+
if unpack_path.parent.exist?
|
216
216
|
unpack_path.parent.rmtree
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
220
220
|
# Remove the downloaded module release.
|
221
221
|
def cleanup_download_path
|
222
|
-
if download_path.exist?
|
222
|
+
if download_path.parent.exist?
|
223
223
|
download_path.parent.rmtree
|
224
224
|
end
|
225
225
|
end
|
data/lib/r10k/git/cache.rb
CHANGED
@@ -16,7 +16,17 @@ class R10K::Git::Cache
|
|
16
16
|
|
17
17
|
include R10K::Settings::Mixin
|
18
18
|
|
19
|
-
|
19
|
+
#@api private
|
20
|
+
def self.determine_cache_root
|
21
|
+
if R10K::Util::Platform.windows?
|
22
|
+
File.join(ENV['LOCALAPPDATA'], 'r10k', 'git')
|
23
|
+
else
|
24
|
+
File.expand_path(ENV['HOME'] ? '~/.r10k/git': '/root/.r10k/git')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
private_class_method :determine_cache_root
|
28
|
+
|
29
|
+
def_setting_attr :cache_root, determine_cache_root
|
20
30
|
|
21
31
|
@instance_cache = R10K::InstanceCache.new(self)
|
22
32
|
|
@@ -99,10 +109,8 @@ class R10K::Git::Cache
|
|
99
109
|
|
100
110
|
alias cached? exist?
|
101
111
|
|
102
|
-
private
|
103
|
-
|
104
112
|
# Reformat the remote name into something that can be used as a directory
|
105
113
|
def sanitized_dirname
|
106
|
-
@remote.gsub(/[^@\w\.-]/, '-')
|
114
|
+
@sanitized_dirname ||= @remote.gsub(/[^@\w\.-]/, '-')
|
107
115
|
end
|
108
116
|
end
|
data/lib/r10k/initializers.rb
CHANGED
data/lib/r10k/module/base.rb
CHANGED
@@ -99,6 +99,14 @@ class R10K::Module::Base
|
|
99
99
|
raise NotImplementedError
|
100
100
|
end
|
101
101
|
|
102
|
+
# Return the module's cachedir. Subclasses that implement a cache
|
103
|
+
# will override this to return a real directory location.
|
104
|
+
#
|
105
|
+
# @return [String, :none]
|
106
|
+
def cachedir
|
107
|
+
:none
|
108
|
+
end
|
109
|
+
|
102
110
|
private
|
103
111
|
|
104
112
|
def parse_title(title)
|
data/lib/r10k/module/git.rb
CHANGED
data/lib/r10k/puppetfile.rb
CHANGED
@@ -10,7 +10,7 @@ class Puppetfile
|
|
10
10
|
|
11
11
|
include R10K::Settings::Mixin
|
12
12
|
|
13
|
-
def_setting_attr :pool_size,
|
13
|
+
def_setting_attr :pool_size, 4
|
14
14
|
|
15
15
|
include R10K::Logging
|
16
16
|
|
@@ -42,6 +42,11 @@ class Puppetfile
|
|
42
42
|
# @return [Boolean] Overwrite any locally made changes
|
43
43
|
attr_accessor :force
|
44
44
|
|
45
|
+
# @!attribute [r] modules_by_vcs_cachedir
|
46
|
+
# @api private Only exposed for testing purposes
|
47
|
+
# @return [Hash{:none, String => Array<R10K::Module>}]
|
48
|
+
attr_reader :modules_by_vcs_cachedir
|
49
|
+
|
45
50
|
# @param [String] basedir
|
46
51
|
# @param [String] moduledir The directory to install the modules, default to #{basedir}/modules
|
47
52
|
# @param [String] puppetfile_path The path to the Puppetfile, default to #{basedir}/Puppetfile
|
@@ -58,6 +63,7 @@ class Puppetfile
|
|
58
63
|
|
59
64
|
@modules = []
|
60
65
|
@managed_content = {}
|
66
|
+
@modules_by_vcs_cachedir = {}
|
61
67
|
@forge = 'forgeapi.puppetlabs.com'
|
62
68
|
|
63
69
|
@loaded = false
|
@@ -137,6 +143,9 @@ class Puppetfile
|
|
137
143
|
mod.origin = 'Puppetfile'
|
138
144
|
|
139
145
|
@managed_content[install_path] << mod.name
|
146
|
+
cachedir = mod.cachedir
|
147
|
+
@modules_by_vcs_cachedir[cachedir] ||= []
|
148
|
+
@modules_by_vcs_cachedir[cachedir] << mod
|
140
149
|
@modules << mod
|
141
150
|
end
|
142
151
|
|
@@ -145,7 +154,9 @@ class Puppetfile
|
|
145
154
|
def managed_directories
|
146
155
|
self.load unless @loaded
|
147
156
|
|
148
|
-
@managed_content.keys
|
157
|
+
dirs = @managed_content.keys
|
158
|
+
dirs.delete(real_basedir)
|
159
|
+
dirs
|
149
160
|
end
|
150
161
|
|
151
162
|
# Returns an array of the full paths to all the content being managed.
|
@@ -212,15 +223,22 @@ class Puppetfile
|
|
212
223
|
def modules_queue(visitor)
|
213
224
|
Queue.new.tap do |queue|
|
214
225
|
visitor.visit(:puppetfile, self) do
|
215
|
-
|
226
|
+
modules_by_cachedir = modules_by_vcs_cachedir.clone
|
227
|
+
modules_without_vcs_cachedir = modules_by_cachedir.delete(:none) || []
|
228
|
+
|
229
|
+
modules_without_vcs_cachedir.each {|mod| queue << Array(mod) }
|
230
|
+
modules_by_cachedir.values.each {|mods| queue << mods }
|
216
231
|
end
|
217
232
|
end
|
218
233
|
end
|
234
|
+
public :modules_queue
|
219
235
|
|
220
236
|
def visitor_thread(visitor, mods_queue)
|
221
237
|
Thread.new do
|
222
238
|
begin
|
223
|
-
while
|
239
|
+
while mods = mods_queue.pop(true) do
|
240
|
+
mods.each {|mod| mod.accept(visitor) }
|
241
|
+
end
|
224
242
|
rescue ThreadError => e
|
225
243
|
logger.debug _("Module thread %{id} exiting: %{message}") % {message: e.message, id: Thread.current.object_id}
|
226
244
|
Thread.exit
|
@@ -248,8 +266,6 @@ class Puppetfile
|
|
248
266
|
end
|
249
267
|
|
250
268
|
def validate_install_path(path, modname)
|
251
|
-
real_basedir = Pathname.new(basedir).cleanpath.to_s
|
252
|
-
|
253
269
|
unless /^#{Regexp.escape(real_basedir)}.*/ =~ path
|
254
270
|
raise R10K::Error.new("Puppetfile cannot manage content '#{modname}' outside of containing environment: #{path} is not within #{real_basedir}")
|
255
271
|
end
|
@@ -257,6 +273,10 @@ class Puppetfile
|
|
257
273
|
true
|
258
274
|
end
|
259
275
|
|
276
|
+
def real_basedir
|
277
|
+
Pathname.new(basedir).cleanpath.to_s
|
278
|
+
end
|
279
|
+
|
260
280
|
class DSL
|
261
281
|
# A barebones implementation of the Puppetfile DSL
|
262
282
|
#
|