r10k 3.14.1 → 5.0.1

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.
Files changed (246) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +17 -0
  3. data/.github/workflows/docker.yml +9 -4
  4. data/.github/workflows/release.yml +3 -2
  5. data/.github/workflows/rspec_tests.yml +8 -10
  6. data/CHANGELOG.mkd +100 -0
  7. data/CODEOWNERS +1 -2
  8. data/Gemfile +2 -2
  9. data/README.mkd +18 -19
  10. data/doc/common-patterns.mkd +1 -2
  11. data/doc/dynamic-environments/configuration.mkd +91 -12
  12. data/doc/dynamic-environments/usage.mkd +4 -0
  13. data/doc/dynamic-environments/workflow-guide.mkd +3 -3
  14. data/doc/faq.mkd +1 -1
  15. data/doc/puppetfile.mkd +9 -3
  16. data/integration/Gemfile +3 -4
  17. data/integration/Rakefile +58 -23
  18. data/integration/files/pre-suite/git_config.pp.erb +1 -1
  19. data/integration/pre-suite/00_pe_install.rb +3 -0
  20. data/integration/pre-suite/10_git_config.rb +1 -3
  21. data/integration/tests/Puppetfile/HTTP_PROXY_affects_git_source.rb +5 -4
  22. data/integration/tests/basic_functionality/negative/negative_bad_proxy.rb +1 -1
  23. data/integration/tests/basic_functionality/proxy_specified_in_configuration.rb +2 -2
  24. data/integration/tests/basic_functionality/proxy_with_puppetfile.rb +2 -2
  25. data/integration/tests/basic_functionality/rugged_git_provider_with_ssh.rb +3 -3
  26. data/integration/tests/basic_functionality/rugged_git_provider_without_ssh.rb +3 -3
  27. data/integration/tests/command_line/deploy_env_without_mod_update.rb +0 -3
  28. data/integration/tests/command_line/negative/neg_deploy_env_with_module_update.rb +0 -3
  29. data/integration/tests/git_source/HTTP_proxy_and_git_source.rb +5 -10
  30. data/integration/tests/git_source/git_source_git.rb +1 -4
  31. data/integration/tests/git_source/git_source_repeated_remote.rb +2 -5
  32. data/integration/tests/git_source/git_source_submodule.rb +1 -1
  33. data/integration/tests/git_source/negative/neg_git_unauthorized_ssh.rb +1 -1
  34. data/integration/tests/purging/content_not_purged_at_root.rb +2 -5
  35. data/integration/tests/purging/default_purging.rb +0 -3
  36. data/integration/tests/purging/{does_not_purge_files_on_white_list.rb → does_not_purge_files_on_allowlist.rb} +2 -5
  37. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module.rb +1 -4
  38. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module_static.rb +1 -4
  39. data/integration/tests/user_scenario/basic_workflow/multi_source_custom_forge_git_module.rb +1 -4
  40. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_forge_module.rb +0 -3
  41. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module.rb +1 -1
  42. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module_ref.rb +1 -1
  43. data/integration/tests/user_scenario/basic_workflow/negative/neg_disk_full.rb +1 -1
  44. data/integration/tests/user_scenario/basic_workflow/negative/neg_duplicate_module_names.rb +0 -3
  45. data/integration/tests/user_scenario/basic_workflow/negative/neg_inaccessible_forge.rb +3 -2
  46. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +1 -5
  47. data/integration/tests/user_scenario/basic_workflow/single_env_10000_files.rb +1 -1
  48. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_git_module.rb +1 -4
  49. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_module.rb +0 -3
  50. data/integration/tests/user_scenario/basic_workflow/single_env_large_files.rb +1 -1
  51. data/integration/tests/user_scenario/basic_workflow/single_env_module_already_installed.rb +0 -3
  52. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +0 -3
  53. data/integration/tests/user_scenario/basic_workflow/single_env_switch_forge_git_module.rb +1 -4
  54. data/integration/tests/user_scenario/basic_workflow/single_env_upgrade_forge_mod_revert_change.rb +0 -3
  55. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +0 -3
  56. data/lib/r10k/action/deploy/environment.rb +2 -19
  57. data/lib/r10k/action/deploy/module.rb +1 -0
  58. data/lib/r10k/action/puppetfile/check.rb +7 -0
  59. data/lib/r10k/action/puppetfile/install.rb +3 -1
  60. data/lib/r10k/cli/deploy.rb +15 -1
  61. data/lib/r10k/cli/puppetfile.rb +1 -0
  62. data/lib/r10k/content_synchronizer.rb +7 -2
  63. data/lib/r10k/environment/with_modules.rb +24 -1
  64. data/lib/r10k/environment.rb +0 -1
  65. data/lib/r10k/git/rugged/bare_repository.rb +5 -4
  66. data/lib/r10k/git/rugged/thin_repository.rb +7 -0
  67. data/lib/r10k/git/rugged/working_repository.rb +13 -7
  68. data/lib/r10k/git/shellgit/thin_repository.rb +5 -1
  69. data/lib/r10k/git/shellgit/working_repository.rb +5 -4
  70. data/lib/r10k/git/stateful_repository.rb +4 -4
  71. data/lib/r10k/module/base.rb +3 -3
  72. data/lib/r10k/module/git.rb +19 -5
  73. data/lib/r10k/module_loader/puppetfile/dsl.rb +4 -0
  74. data/lib/r10k/module_loader/puppetfile.rb +22 -14
  75. data/lib/r10k/puppetfile.rb +1 -1
  76. data/lib/r10k/settings/container.rb +1 -0
  77. data/lib/r10k/settings.rb +6 -7
  78. data/lib/r10k/tarball.rb +1 -1
  79. data/lib/r10k/version.rb +1 -1
  80. data/locales/r10k.pot +34 -82
  81. data/r10k.gemspec +8 -18
  82. metadata +40 -213
  83. data/.github/workflows/stale.yml +0 -21
  84. data/.travis.yml +0 -42
  85. data/docker/.gitignore +0 -1
  86. data/docker/.rspec +0 -4
  87. data/docker/Gemfile +0 -11
  88. data/docker/Makefile +0 -92
  89. data/docker/README.md +0 -28
  90. data/docker/docker-compose.yml +0 -18
  91. data/docker/r10k/Dockerfile +0 -68
  92. data/docker/r10k/adduser.sh +0 -13
  93. data/docker/r10k/docker-entrypoint.d/10-analytics.sh +0 -30
  94. data/docker/r10k/docker-entrypoint.sh +0 -10
  95. data/docker/r10k/release.Dockerfile +0 -55
  96. data/docker/spec/dockerfile_spec.rb +0 -37
  97. data/docker/spec/fixtures/Puppetfile +0 -2
  98. data/integration/tests/basic_functionality/install_pe_only_module_with_puppetfile.rb +0 -83
  99. data/integration/tests/basic_functionality/proxy_with_pe_only_module.rb +0 -128
  100. data/integration/tests/purging/invalid_whitelist_types.rb +0 -63
  101. data/integration/tests/user_scenario/basic_workflow/negative/neg_module_specified_at_deleted_release.rb +0 -49
  102. data/integration/tests/user_scenario/basic_workflow/single_env_module_last_release_deleted.rb +0 -68
  103. data/lib/r10k/environment/bare.rb +0 -13
  104. data/spec/fixtures/empty/.empty +0 -0
  105. data/spec/fixtures/integration/git/puppet-boolean-bare.tar +0 -0
  106. data/spec/fixtures/module/forge/bad_module/metadata.json +0 -1
  107. data/spec/fixtures/module/forge/eight_hundred/Modulefile +0 -8
  108. data/spec/fixtures/module/forge/eight_hundred/metadata.json +0 -19
  109. data/spec/fixtures/tarball/tarball.tar.gz +0 -0
  110. data/spec/fixtures/unit/action/r10k.yaml +0 -5
  111. data/spec/fixtures/unit/action/r10k_cachedir.yaml +0 -2
  112. data/spec/fixtures/unit/action/r10k_creds.yaml +0 -9
  113. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +0 -4
  114. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +0 -3
  115. data/spec/fixtures/unit/action/r10k_generate_types.yaml +0 -3
  116. data/spec/fixtures/unit/action/r10k_logging.yaml +0 -12
  117. data/spec/fixtures/unit/action/r10k_puppet_path.yaml +0 -3
  118. data/spec/fixtures/unit/puppetfile/argument-error/Puppetfile +0 -1
  119. data/spec/fixtures/unit/puppetfile/default-branch-override/Puppetfile +0 -5
  120. data/spec/fixtures/unit/puppetfile/duplicate-module-error/Puppetfile +0 -10
  121. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +0 -8
  122. data/spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile +0 -1
  123. data/spec/fixtures/unit/puppetfile/load-error/Puppetfile +0 -1
  124. data/spec/fixtures/unit/puppetfile/name-error/Puppetfile +0 -1
  125. data/spec/fixtures/unit/puppetfile/valid-forge-with-version/Puppetfile +0 -1
  126. data/spec/fixtures/unit/puppetfile/valid-forge-without-version/Puppetfile +0 -1
  127. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +0 -10
  128. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +0 -10
  129. data/spec/fixtures/unit/util/purgeable/managed_one/expected_1 +0 -0
  130. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_symlink_file +0 -1
  131. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_allowlisted_2/ignored_1 +0 -0
  132. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_expected_1 +0 -0
  133. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_unmanaged_1 +0 -0
  134. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/unmanaged_symlink_dir +0 -1
  135. data/spec/fixtures/unit/util/purgeable/managed_one/managed_symlink_dir +0 -1
  136. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_1 +0 -0
  137. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_symlink_file +0 -1
  138. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  139. data/spec/fixtures/unit/util/purgeable/managed_two/expected_2 +0 -0
  140. data/spec/fixtures/unit/util/purgeable/managed_two/unmanaged_2 +0 -0
  141. data/spec/fixtures/unit/util/subprocess/runner/no-execute.sh +0 -3
  142. data/spec/integration/git/rugged/bare_repository_spec.rb +0 -13
  143. data/spec/integration/git/rugged/cache_spec.rb +0 -33
  144. data/spec/integration/git/rugged/thin_repository_spec.rb +0 -14
  145. data/spec/integration/git/rugged/working_repository_spec.rb +0 -48
  146. data/spec/integration/git/shellgit/bare_repository_spec.rb +0 -13
  147. data/spec/integration/git/shellgit/thin_repository_spec.rb +0 -14
  148. data/spec/integration/git/shellgit/working_repository_spec.rb +0 -13
  149. data/spec/integration/git/stateful_repository_spec.rb +0 -159
  150. data/spec/integration/util/purageable_spec.rb +0 -41
  151. data/spec/matchers/exit_with.rb +0 -28
  152. data/spec/matchers/match_realpath.rb +0 -18
  153. data/spec/r10k-mocks/mock_config.rb +0 -33
  154. data/spec/r10k-mocks/mock_env.rb +0 -18
  155. data/spec/r10k-mocks/mock_source.rb +0 -17
  156. data/spec/r10k-mocks.rb +0 -3
  157. data/spec/shared-contexts/git-fixtures.rb +0 -55
  158. data/spec/shared-contexts/tarball.rb +0 -32
  159. data/spec/shared-examples/deploy-actions.rb +0 -69
  160. data/spec/shared-examples/git/bare_repository.rb +0 -132
  161. data/spec/shared-examples/git/thin_repository.rb +0 -26
  162. data/spec/shared-examples/git/working_repository.rb +0 -207
  163. data/spec/shared-examples/git-repository.rb +0 -38
  164. data/spec/shared-examples/puppetfile-action.rb +0 -39
  165. data/spec/shared-examples/settings/ancestry.rb +0 -44
  166. data/spec/shared-examples/subprocess-runner.rb +0 -89
  167. data/spec/spec_helper.rb +0 -41
  168. data/spec/unit/action/cri_runner_spec.rb +0 -72
  169. data/spec/unit/action/deploy/deploy_helpers_spec.rb +0 -38
  170. data/spec/unit/action/deploy/display_spec.rb +0 -61
  171. data/spec/unit/action/deploy/environment_spec.rb +0 -640
  172. data/spec/unit/action/deploy/module_spec.rb +0 -476
  173. data/spec/unit/action/puppetfile/check_spec.rb +0 -53
  174. data/spec/unit/action/puppetfile/cri_runner_spec.rb +0 -47
  175. data/spec/unit/action/puppetfile/install_spec.rb +0 -112
  176. data/spec/unit/action/puppetfile/purge_spec.rb +0 -60
  177. data/spec/unit/action/runner_spec.rb +0 -407
  178. data/spec/unit/action/visitor_spec.rb +0 -39
  179. data/spec/unit/cli_spec.rb +0 -9
  180. data/spec/unit/deployment/config_spec.rb +0 -33
  181. data/spec/unit/deployment_spec.rb +0 -162
  182. data/spec/unit/environment/bare_spec.rb +0 -13
  183. data/spec/unit/environment/base_spec.rb +0 -122
  184. data/spec/unit/environment/git_spec.rb +0 -114
  185. data/spec/unit/environment/name_spec.rb +0 -181
  186. data/spec/unit/environment/plain_spec.rb +0 -8
  187. data/spec/unit/environment/svn_spec.rb +0 -146
  188. data/spec/unit/environment/tarball_spec.rb +0 -45
  189. data/spec/unit/environment/with_modules_spec.rb +0 -75
  190. data/spec/unit/errors/formatting_spec.rb +0 -84
  191. data/spec/unit/feature_spec.rb +0 -50
  192. data/spec/unit/forge/module_release_spec.rb +0 -213
  193. data/spec/unit/git/alternates_spec.rb +0 -116
  194. data/spec/unit/git/cache_spec.rb +0 -66
  195. data/spec/unit/git/rugged/cache_spec.rb +0 -48
  196. data/spec/unit/git/rugged/credentials_spec.rb +0 -215
  197. data/spec/unit/git/shellgit/cache_spec.rb +0 -27
  198. data/spec/unit/git/stateful_repository_spec.rb +0 -45
  199. data/spec/unit/git_spec.rb +0 -102
  200. data/spec/unit/initializers_spec.rb +0 -68
  201. data/spec/unit/instance_cache_spec.rb +0 -78
  202. data/spec/unit/keyed_factory_spec.rb +0 -51
  203. data/spec/unit/logging/terminaloutputter_spec.rb +0 -53
  204. data/spec/unit/logging_spec.rb +0 -68
  205. data/spec/unit/module/base_spec.rb +0 -118
  206. data/spec/unit/module/forge_spec.rb +0 -271
  207. data/spec/unit/module/git_spec.rb +0 -387
  208. data/spec/unit/module/metadata_file_spec.rb +0 -68
  209. data/spec/unit/module/svn_spec.rb +0 -208
  210. data/spec/unit/module/tarball_spec.rb +0 -70
  211. data/spec/unit/module_loader/puppetfile_spec.rb +0 -421
  212. data/spec/unit/module_spec.rb +0 -114
  213. data/spec/unit/puppetfile_spec.rb +0 -304
  214. data/spec/unit/settings/collection_spec.rb +0 -123
  215. data/spec/unit/settings/container_spec.rb +0 -92
  216. data/spec/unit/settings/definition_spec.rb +0 -79
  217. data/spec/unit/settings/enum_definition_spec.rb +0 -20
  218. data/spec/unit/settings/inheritance_spec.rb +0 -38
  219. data/spec/unit/settings/list_spec.rb +0 -88
  220. data/spec/unit/settings/loader_spec.rb +0 -110
  221. data/spec/unit/settings/uri_definition_spec.rb +0 -23
  222. data/spec/unit/settings_spec.rb +0 -303
  223. data/spec/unit/source/base_spec.rb +0 -31
  224. data/spec/unit/source/exec_spec.rb +0 -81
  225. data/spec/unit/source/git_spec.rb +0 -233
  226. data/spec/unit/source/hash_spec.rb +0 -54
  227. data/spec/unit/source/svn_spec.rb +0 -196
  228. data/spec/unit/source/yaml_spec.rb +0 -42
  229. data/spec/unit/source_spec.rb +0 -10
  230. data/spec/unit/svn/remote_spec.rb +0 -21
  231. data/spec/unit/svn/working_dir_spec.rb +0 -56
  232. data/spec/unit/tarball_spec.rb +0 -57
  233. data/spec/unit/util/attempt_spec.rb +0 -82
  234. data/spec/unit/util/cacheable_spec.rb +0 -23
  235. data/spec/unit/util/commands_spec.rb +0 -61
  236. data/spec/unit/util/downloader_spec.rb +0 -98
  237. data/spec/unit/util/exec_env_spec.rb +0 -56
  238. data/spec/unit/util/purgeable_spec.rb +0 -267
  239. data/spec/unit/util/setopts_spec.rb +0 -83
  240. data/spec/unit/util/subprocess/result_spec.rb +0 -36
  241. data/spec/unit/util/subprocess/runner/posix_spec.rb +0 -7
  242. data/spec/unit/util/subprocess/runner/pump_spec.rb +0 -79
  243. data/spec/unit/util/subprocess/runner/windows_spec.rb +0 -7
  244. data/spec/unit/util/subprocess/subprocess_error_spec.rb +0 -26
  245. data/spec/unit/util/subprocess_spec.rb +0 -65
  246. data/spec/unit/util/symbolize_keys_spec.rb +0 -67
@@ -45,9 +45,6 @@ teardown do
45
45
  end
46
46
 
47
47
  #Setup
48
- step 'Stub Forge on Master'
49
- stub_forge_on(master)
50
-
51
48
  step 'Checkout "production" Branch'
52
49
  git_on(master, 'checkout production', git_environments_path)
53
50
 
@@ -3,7 +3,7 @@ require 'r10k_utils'
3
3
  require 'master_manipulator'
4
4
  test_name 'CODEMGMT-62 - C59242 - Single Environment with Large Binary Files'
5
5
 
6
- if fact_on(master, 'osfamily') == 'RedHat' and fact_on(master, "operatingsystemmajrelease").to_i < 6
6
+ if fact_on(master, 'os.family') == 'RedHat' and fact_on(master, "os.release.major").to_i < 6
7
7
  skip_test('This version of EL is not supported by this test case!')
8
8
  end
9
9
 
@@ -44,9 +44,6 @@ teardown do
44
44
  end
45
45
 
46
46
  #Setup
47
- step 'Stub Forge on Master'
48
- stub_forge_on(master)
49
-
50
47
  step 'Add motd module from the forge using the PMT'
51
48
  on(master, puppet('module', 'install', 'puppetlabs-motd', '--modulepath', forge_module_path))
52
49
 
@@ -43,9 +43,6 @@ teardown do
43
43
  end
44
44
 
45
45
  #Setup
46
- step 'Stub Forge on Master'
47
- stub_forge_on(master)
48
-
49
46
  step 'Checkout "production" Branch'
50
47
  git_on(master, 'checkout production', git_remote_environments_path)
51
48
 
@@ -27,7 +27,7 @@ PUPPETFILE
27
27
 
28
28
  puppet_file_git = <<-PUPPETFILE
29
29
  mod "puppetlabs/motd",
30
- :git => 'git://github.com/puppetlabs/puppetlabs-motd',
30
+ :git => 'https://github.com/puppetlabs/puppetlabs-motd',
31
31
  :tag => '1.2.0'
32
32
  PUPPETFILE
33
33
 
@@ -57,9 +57,6 @@ teardown do
57
57
  end
58
58
 
59
59
  #Setup
60
- step 'Stub Forge on Master'
61
- stub_forge_on(master)
62
-
63
60
  step 'Checkout "production" Branch'
64
61
  git_on(master, 'checkout production', git_environments_path)
65
62
 
@@ -60,9 +60,6 @@ teardown do
60
60
  end
61
61
 
62
62
  #Setup
63
- step 'Stub Forge on Master'
64
- stub_forge_on(master)
65
-
66
63
  step 'Checkout "production" Branch'
67
64
  git_on(master, 'checkout production', git_environments_path)
68
65
 
@@ -65,9 +65,6 @@ teardown do
65
65
  end
66
66
 
67
67
  #Setup
68
- step 'Stub Forge on Master'
69
- stub_forge_on(master)
70
-
71
68
  initial_env_names.each do |env|
72
69
  if env == 'production'
73
70
  step "Checkout \"#{env}\" Branch"
@@ -45,6 +45,7 @@ module R10K
45
45
  incremental: @incremental
46
46
  },
47
47
  modules: {
48
+ default_ref: settings.dig(:git, :default_ref),
48
49
  exclude_spec: settings.dig(:deploy, :exclude_spec),
49
50
  requested_modules: [],
50
51
  deploy_modules: @modules,
@@ -53,8 +54,7 @@ module R10K
53
54
  },
54
55
  purging: {
55
56
  purge_levels: settings.dig(:deploy, :purge_levels) || [],
56
- purge_allowlist: read_purge_allowlist(settings.dig(:deploy, :purge_whitelist) || [],
57
- settings.dig(:deploy, :purge_allowlist) || [])
57
+ purge_allowlist: settings.dig(:deploy, :purge_allowlist) || []
58
58
  },
59
59
  forge: {
60
60
  allow_puppetfile_override: settings.dig(:forge, :allow_puppetfile_override) || false
@@ -83,23 +83,6 @@ module R10K
83
83
 
84
84
  private
85
85
 
86
- def read_purge_allowlist (whitelist, allowlist)
87
- whitelist_has_content = !whitelist.empty?
88
- allowlist_has_content = !allowlist.empty?
89
- case
90
- when whitelist_has_content == false && allowlist_has_content == false
91
- []
92
- when whitelist_has_content && allowlist_has_content
93
- raise R10K::Error.new "Values found for both purge_whitelist and purge_allowlist. Setting " <<
94
- "purge_whitelist is deprecated, please only use purge_allowlist."
95
- when allowlist_has_content
96
- allowlist
97
- else
98
- logger.warn "Setting purge_whitelist is deprecated; please use purge_allowlist instead."
99
- whitelist
100
- end
101
- end
102
-
103
86
  def visit_deployment(deployment)
104
87
  # Ensure that everything can be preloaded. If we cannot preload all
105
88
  # sources then we can't fully enumerate all environments which
@@ -39,6 +39,7 @@ module R10K
39
39
  generate_types: @generate_types
40
40
  },
41
41
  modules: {
42
+ default_ref: settings.dig(:git, :default_ref),
42
43
  exclude_spec: settings.dig(:deploy, :exclude_spec),
43
44
  pool_size: @settings[:pool_size] || 4,
44
45
  requested_modules: @argv.map.to_a,
@@ -9,12 +9,19 @@ module R10K
9
9
 
10
10
  def call
11
11
  options = { basedir: @root }
12
+ options[:overrides] = {}
13
+ options[:overrides][:modules] = { default_ref: @settings.dig(:git, :default_ref) }
12
14
  options[:moduledir] = @moduledir if @moduledir
13
15
  options[:puppetfile] = @puppetfile if @puppetfile
14
16
 
15
17
  loader = R10K::ModuleLoader::Puppetfile.new(**options)
16
18
  begin
17
19
  loader.load!
20
+ loader.modules.each do |mod|
21
+ if mod.instance_of?(R10K::Module::Git)
22
+ mod.validate_ref_defined
23
+ end
24
+ end
18
25
  $stderr.puts _("Syntax OK")
19
26
  true
20
27
  rescue => e
@@ -12,8 +12,10 @@ module R10K
12
12
  def call
13
13
  begin
14
14
  options = { basedir: @root, overrides: { force: @force || false } }
15
+ options[:overrides][:modules] = { default_ref: @settings.dig(:git, :default_ref) }
15
16
  options[:moduledir] = @moduledir if @moduledir
16
17
  options[:puppetfile] = @puppetfile if @puppetfile
18
+ options[:module_exclude_regex] = @module_exclude_regex if @module_exclude_regex
17
19
 
18
20
  loader = R10K::ModuleLoader::Puppetfile.new(**options)
19
21
  loaded_content = loader.load!
@@ -40,7 +42,7 @@ module R10K
40
42
  private
41
43
 
42
44
  def allowed_initialize_opts
43
- super.merge(root: :self, puppetfile: :self, moduledir: :self, force: :self )
45
+ super.merge(root: :self, puppetfile: :self, moduledir: :self, :'module-exclude-regex' => :self, force: :self )
44
46
  end
45
47
  end
46
48
  end
@@ -10,6 +10,19 @@ require 'cri'
10
10
 
11
11
  module R10K::CLI
12
12
  module Deploy
13
+
14
+ class TransformExcludeSpec
15
+ def call(input)
16
+ # To be backward compatible with the 3.x flag version of this setting,
17
+ # r10k allows this flag to have an optional argument. When no argument
18
+ # is supplied, cri defaults to setting the class to true, so we check
19
+ # for TrueClass here as well as "true".
20
+ return true if input == true || input == 'true'
21
+ return false if input == 'false'
22
+ raise ArgumentError
23
+ end
24
+ end
25
+
13
26
  def self.command
14
27
  @cmd ||= Cri::Command.define do
15
28
  name 'deploy'
@@ -24,7 +37,8 @@ module R10K::CLI
24
37
  option nil, :cachedir, 'Specify a cachedir, overriding the value in config', argument: :required
25
38
  flag nil, :'no-force', 'Prevent the overwriting of local module modifications'
26
39
  flag nil, :'generate-types', 'Run `puppet generate types` after updating an environment'
27
- flag nil, :'exclude-spec', 'Exclude the module\'s spec dir from deployment'
40
+ option nil, :'exclude-spec', 'Exclude the module\'s spec dir for deployment', argument: :optional,
41
+ transform: TransformExcludeSpec.new
28
42
  option nil, :'puppet-path', 'Path to puppet executable', argument: :required do |value, cmd|
29
43
  unless File.executable? value
30
44
  $stderr.puts "The specified puppet executable #{value} is not executable."
@@ -31,6 +31,7 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
31
31
  summary 'Install all modules from a Puppetfile'
32
32
  option nil, :moduledir, 'Path to install modules to', argument: :required
33
33
  option nil, :puppetfile, 'Path to puppetfile', argument: :required
34
+ option nil, :'module-exclude-regex', 'A regex to exclude modules from installation. Helpful in CI environments.', argument: :required
34
35
  flag nil, :force, 'Force locally changed files to be overwritten'
35
36
  runner R10K::Action::Puppetfile::CriRunner.wrap(R10K::Action::Puppetfile::Install)
36
37
  end
@@ -79,8 +79,13 @@ module R10K
79
79
  begin
80
80
  while mods = mods_queue.pop(true) do
81
81
  mods.each do |mod|
82
- updated = mod.sync
83
- updated_modules << mod.name if updated
82
+ begin
83
+ updated = mod.sync
84
+ updated_modules << mod.name if updated
85
+ rescue Exception => e
86
+ logger.error _("Module %{mod_name} failed to synchronize due to %{message}") % {mod_name: mod.name, message: e.message}
87
+ raise e
88
+ end
84
89
  end
85
90
  end
86
91
  rescue ThreadError => e
@@ -103,6 +103,29 @@ class R10K::Environment::WithModules < R10K::Environment::Base
103
103
  end
104
104
  end
105
105
 
106
+ def resolve_path(base, dirname, path)
107
+ if Pathname.new(path).absolute?
108
+ cleanpath(path)
109
+ else
110
+ cleanpath(File.join(base, dirname, path))
111
+ end
112
+ end
113
+
114
+ # .cleanpath is as good as we can do without touching the filesystem.
115
+ # The .realpath methods will choke if some of the intermediate paths
116
+ # are missing, even though in some cases we will create them later as
117
+ # needed.
118
+ def cleanpath(path)
119
+ Pathname.new(path).cleanpath.to_s
120
+ end
121
+
122
+ def validate_install_path(path, modname)
123
+ unless /^#{Regexp.escape(@basedir)}.*/ =~ path
124
+ raise R10K::Error.new("Environment cannot manage content '#{modname}' outside of containing environment: #{path} is not within #{@basedir}")
125
+ end
126
+ true
127
+ end
128
+
106
129
  # @param [String] name
107
130
  # @param [Hash] args
108
131
  def add_module(name, args)
@@ -111,7 +134,7 @@ class R10K::Environment::WithModules < R10K::Environment::Base
111
134
  args[:overrides] = @overrides
112
135
 
113
136
  if install_path = args.delete(:install_path)
114
- install_path = resolve_install_path(install_path)
137
+ install_path = resolve_path(@basedir, @dirname, install_path)
115
138
  validate_install_path(install_path, name)
116
139
  else
117
140
  install_path = @moduledir
@@ -31,7 +31,6 @@ module R10K
31
31
  require 'r10k/environment/base'
32
32
  require 'r10k/environment/with_modules'
33
33
  require 'r10k/environment/plain'
34
- require 'r10k/environment/bare'
35
34
  require 'r10k/environment/git'
36
35
  require 'r10k/environment/svn'
37
36
  require 'r10k/environment/tarball'
@@ -36,7 +36,7 @@ class R10K::Git::Rugged::BareRepository < R10K::Git::Rugged::BaseRepository
36
36
  @_rugged_repo = ::Rugged::Repository.init_at(@path.to_s, true).tap do |repo|
37
37
  config = repo.config
38
38
  config['remote.origin.url'] = remote
39
- config['remote.origin.fetch'] = '+refs/*:refs/*'
39
+ config['remote.origin.fetch'] = '+refs/heads/*:refs/heads/*'
40
40
  config['remote.origin.mirror'] = 'true'
41
41
  end
42
42
 
@@ -56,11 +56,12 @@ class R10K::Git::Rugged::BareRepository < R10K::Git::Rugged::BaseRepository
56
56
  logger.warn { _("Rugged versions prior to 0.24.0 do not support pruning stale branches during fetch, please upgrade your \'rugged\' gem. (Current version is: %{version})") % {version: Rugged::Version} }
57
57
  end
58
58
 
59
- options = {:credentials => credentials, :prune => true}
60
- refspecs = ['+refs/*:refs/*']
61
-
62
59
  remote = remotes[remote_name]
63
60
  proxy = R10K::Git.get_proxy_for_remote(remote)
61
+
62
+ options = {:credentials => credentials, :prune => true, :proxy_url => proxy, :download_tags => true}
63
+ refspecs = ['+refs/heads/*:refs/heads/*', '+refs/tags/*:refs/tags/*']
64
+
64
65
  results = nil
65
66
 
66
67
  R10K::Git.with_proxy(proxy) do
@@ -75,6 +75,13 @@ class R10K::Git::Rugged::ThinRepository < R10K::Git::Rugged::WorkingRepository
75
75
  end
76
76
  end
77
77
 
78
+ def stage_files(files=['.'])
79
+ with_repo do |repo|
80
+ index = repo.index
81
+ files.each { |p| index.add( :path => p ) }
82
+ end
83
+ end
84
+
78
85
  private
79
86
 
80
87
  # Override the parent class repo setup so that we can make sure the alternates file is up to date
@@ -27,6 +27,7 @@ class R10K::Git::Rugged::WorkingRepository < R10K::Git::Rugged::BaseRepository
27
27
  def clone(remote, opts = {})
28
28
  logger.debug1 { _("Cloning '%{remote}' into %{path}") % {remote: remote, path: @path } }
29
29
 
30
+ proxy = R10K::Git.get_proxy_for_remote(remote)
30
31
  # libgit2/rugged doesn't support cloning a repository and providing an
31
32
  # alternate object database, making the handling of :alternates a noop.
32
33
  # Unfortunately this means that this method can't really use alternates
@@ -34,10 +35,9 @@ class R10K::Git::Rugged::WorkingRepository < R10K::Git::Rugged::BaseRepository
34
35
  # repository. However alternate databases can be handled when an existing
35
36
  # repository is loaded, so loading a cloned repo will correctly use
36
37
  # alternate object database.
37
- options = {:credentials => credentials}
38
+ options = {:credentials => credentials, :proxy_url => proxy}
38
39
  options.merge!(:alternates => [File.join(opts[:reference], 'objects')]) if opts[:reference]
39
40
 
40
- proxy = R10K::Git.get_proxy_for_remote(remote)
41
41
 
42
42
  R10K::Git.with_proxy(proxy) do
43
43
  @_rugged_repo = ::Rugged::Repository.clone_at(remote, @path.to_s, options)
@@ -85,11 +85,13 @@ class R10K::Git::Rugged::WorkingRepository < R10K::Git::Rugged::BaseRepository
85
85
 
86
86
  def fetch(remote_name = 'origin')
87
87
  logger.debug1 { _("Fetching remote '%{remote}' at %{path}") % {remote: remote_name, path: @path} }
88
- options = {:credentials => credentials}
89
- refspecs = ["+refs/heads/*:refs/remotes/#{remote_name}/*"]
90
88
 
91
89
  remote = remotes[remote_name]
92
90
  proxy = R10K::Git.get_proxy_for_remote(remote)
91
+
92
+ options = {:credentials => credentials, :proxy_url => proxy, :prune => true}
93
+ refspecs = ["+refs/heads/*:refs/remotes/#{remote_name}/*"]
94
+
93
95
  results = nil
94
96
 
95
97
  R10K::Git.with_proxy(proxy) do
@@ -117,11 +119,15 @@ class R10K::Git::Rugged::WorkingRepository < R10K::Git::Rugged::BaseRepository
117
119
  with_repo { |repo| repo.config['remote.origin.url'] }
118
120
  end
119
121
 
120
- def dirty?
122
+ def dirty?(exclude_spec=true)
121
123
  with_repo do |repo|
122
- diff = repo.diff_workdir('HEAD')
124
+ if exclude_spec
125
+ diff = repo.diff_workdir('HEAD').select { |d| ! d.delta.old_file[:path].start_with?('spec/') }
126
+ else
127
+ diff = repo.diff_workdir('HEAD').to_a
128
+ end
123
129
 
124
- diff.each_patch do |p|
130
+ diff.each do |p|
125
131
  logger.debug(_("Found local modifications in %{file_path}" % {file_path: File.join(@path, p.delta.old_file[:path])}))
126
132
  logger.debug1(p.to_s)
127
133
  end
@@ -31,7 +31,7 @@ class R10K::Git::ShellGit::ThinRepository < R10K::Git::ShellGit::WorkingReposito
31
31
 
32
32
  # Fetch refs from the backing bare Git repository.
33
33
  def fetch(remote = 'cache')
34
- git ['fetch', remote], :path => @path.to_s
34
+ git ['fetch', remote, '--prune'], :path => @path.to_s
35
35
  end
36
36
 
37
37
  # @return [String] The origin remote URL
@@ -43,6 +43,10 @@ class R10K::Git::ShellGit::ThinRepository < R10K::Git::ShellGit::WorkingReposito
43
43
  git(['ls-tree', '-t', '-r', '--name-only', ref], :path => @path.to_s).stdout.split("\n")
44
44
  end
45
45
 
46
+ def stage_files(files=['.'])
47
+ git(['add', files].flatten, :path => @path.to_s)
48
+ end
49
+
46
50
  private
47
51
 
48
52
  def setup_cache_remote
@@ -90,20 +90,21 @@ class R10K::Git::ShellGit::WorkingRepository < R10K::Git::ShellGit::BaseReposito
90
90
  end
91
91
 
92
92
  # does the working tree have local modifications to tracked files?
93
- def dirty?
93
+ def dirty?(exclude_spec=true)
94
94
  result = git(['diff-index', '--exit-code', '--name-only', 'HEAD'], :path => @path.to_s, :raise_on_fail => false)
95
95
 
96
96
  if result.exit_code != 0
97
- dirty_files = result.stdout.split('\n')
97
+ dirty_files = result.stdout.split("\n")
98
+ dirty_files.delete_if { |f| f.start_with?('spec/') } if exclude_spec
98
99
 
99
100
  dirty_files.each do |file|
100
101
  logger.debug(_("Found local modifications in %{file_path}" % {file_path: File.join(@path, file)}))
101
102
 
102
103
  # Do this in a block so that the extra subprocess only gets invoked when needed.
103
- logger.debug1 { git(['diff-index', '-p', 'HEAD', file], :path => @path.to_s, :raise_on_fail => false).stdout }
104
+ logger.debug1 { git(['diff-index', '-p', 'HEAD', '--', file], :path => @path.to_s, :raise_on_fail => false).stdout }
104
105
  end
105
106
 
106
- return true
107
+ return dirty_files.size > 0
107
108
  else
108
109
  return false
109
110
  end
@@ -36,7 +36,7 @@ class R10K::Git::StatefulRepository
36
36
  end
37
37
 
38
38
  # Returns true if the sync actually updated the repo, false otherwise
39
- def sync(ref, force=true)
39
+ def sync(ref, force=true, exclude_spec=true)
40
40
  @cache.sync if sync_cache?(ref)
41
41
 
42
42
  sha = @cache.resolve(ref)
@@ -45,7 +45,7 @@ class R10K::Git::StatefulRepository
45
45
  raise R10K::Git::UnresolvableRefError.new(_("Unable to sync repo to unresolvable ref '%{ref}'") % {ref: ref}, :git_dir => @repo.git_dir)
46
46
  end
47
47
 
48
- workdir_status = status(ref)
48
+ workdir_status = status(ref, exclude_spec)
49
49
 
50
50
  updated = true
51
51
  case workdir_status
@@ -75,7 +75,7 @@ class R10K::Git::StatefulRepository
75
75
  updated
76
76
  end
77
77
 
78
- def status(ref)
78
+ def status(ref, exclude_spec=true)
79
79
  if !@repo.exist?
80
80
  :absent
81
81
  elsif !@cache.exist?
@@ -88,7 +88,7 @@ class R10K::Git::StatefulRepository
88
88
  :mismatched
89
89
  elsif @repo.head.nil?
90
90
  :mismatched
91
- elsif @repo.dirty?
91
+ elsif @repo.dirty?(exclude_spec)
92
92
  :dirty
93
93
  elsif !(@repo.head == @cache.resolve(ref))
94
94
  :outdated
@@ -60,8 +60,8 @@ class R10K::Module::Base
60
60
  @environment = environment
61
61
  @overrides = args.delete(:overrides) || {}
62
62
  @spec_deletable = true
63
- @exclude_spec = false
64
- @exclude_spec = @overrides.dig(:modules, :exclude_spec) if @overrides.dig(:modules, :exclude_spec)
63
+ @exclude_spec = true
64
+ @exclude_spec = @overrides.dig(:modules, :exclude_spec) unless @overrides.dig(:modules, :exclude_spec).nil?
65
65
  if args.has_key?(:exclude_spec)
66
66
  logger.debug2 _("Overriding :exclude_spec setting with per module setting for #{@title}")
67
67
  @exclude_spec = args.delete(:exclude_spec)
@@ -78,7 +78,7 @@ class R10K::Module::Base
78
78
  path.to_s
79
79
  end
80
80
 
81
- # Delete the spec dir if @exclude_spec has been set to true and @spec_deletable is also true
81
+ # Delete the spec dir if @exclude_spec is true and @spec_deletable is also true
82
82
  def maybe_delete_spec_dir
83
83
  if @exclude_spec
84
84
  if @spec_deletable
@@ -46,6 +46,11 @@ class R10K::Module::Git < R10K::Module::Base
46
46
  # @return [String]
47
47
  attr_reader :default_override_ref
48
48
 
49
+ # @!attribute[r] remote
50
+ # @api private
51
+ # @return [String]
52
+ attr_reader :remote
53
+
49
54
  include R10K::Util::Setopts
50
55
 
51
56
  def initialize(title, dirname, opts, environment=nil)
@@ -63,15 +68,14 @@ class R10K::Module::Git < R10K::Module::Base
63
68
  :commit => :desired_ref,
64
69
  :ref => :desired_ref,
65
70
  :git => :remote,
66
- :default_branch => :default_ref,
71
+ :default_branch => :default_branch,
67
72
  :default_branch_override => :default_override_ref,
68
73
  }, :raise_on_unhandled => false)
69
74
 
75
+ @default_ref = @default_branch.nil? ? @overrides.dig(:modules, :default_ref) : @default_branch
70
76
  force = @overrides[:force]
71
77
  @force = force == false ? false : true
72
78
 
73
- @desired_ref ||= 'master'
74
-
75
79
  if @desired_ref == :control_branch
76
80
  if @environment && @environment.respond_to?(:ref)
77
81
  @desired_ref = @environment.ref
@@ -100,7 +104,7 @@ class R10K::Module::Git < R10K::Module::Base
100
104
  def sync(opts={})
101
105
  force = opts[:force] || @force
102
106
  if should_sync?
103
- updated = @repo.sync(version, force)
107
+ updated = @repo.sync(version, force, @exclude_spec)
104
108
  else
105
109
  updated = false
106
110
  end
@@ -116,6 +120,14 @@ class R10K::Module::Git < R10K::Module::Base
116
120
  @repo.cache.sanitized_dirname
117
121
  end
118
122
 
123
+ def validate_ref_defined
124
+ if @desired_ref.nil? && @default_ref.nil? && @default_override_ref.nil?
125
+ msg = "No ref defined for module #{@name}. Add a ref to the module definition "
126
+ msg << "or set git:default_ref in the r10k.yaml config to configure a global default ref."
127
+ raise ArgumentError, msg
128
+ end
129
+ end
130
+
119
131
  private
120
132
 
121
133
  def validate_ref(desired, default, default_override)
@@ -147,7 +159,9 @@ class R10K::Module::Git < R10K::Module::Base
147
159
  msg << "or resolve default ref '%{default}'"
148
160
  vars[:default] = default
149
161
  else
150
- msg << "and no default provided"
162
+ msg << "and no default provided. r10k no longer hardcodes 'master' as the default ref."
163
+ msg << "Consider setting a ref per module in the Puppetfile or setting git:default_ref"
164
+ msg << "in your r10k config."
151
165
  end
152
166
 
153
167
  raise ArgumentError, _(msg.join(' ')) % vars
@@ -33,6 +33,10 @@ module R10K
33
33
  @librarian.set_moduledir(location)
34
34
  end
35
35
 
36
+ def exclusion(name)
37
+ # noop
38
+ end
39
+
36
40
  def method_missing(method, *args)
37
41
  raise NoMethodError, _("unrecognized declaration '%{method}'") % {method: method}
38
42
  end
@@ -30,17 +30,21 @@ module R10K
30
30
  # @param overrides [Hash] Configuration for loaded modules' behavior
31
31
  # @param environment [R10K::Environment] When provided, the environment
32
32
  # in which loading takes place
33
+ # @param module_exclude_regex [Regex] A regex to exclude modules from
34
+ # installation. Helpful in CI environments.
33
35
  def initialize(basedir:,
34
36
  moduledir: DEFAULT_MODULEDIR,
35
37
  puppetfile: DEFAULT_PUPPETFILE_NAME,
36
38
  overrides: {},
37
- environment: nil)
39
+ environment: nil,
40
+ module_exclude_regex: nil)
38
41
 
39
42
  @basedir = cleanpath(basedir)
40
43
  @moduledir = resolve_path(@basedir, moduledir)
41
44
  @puppetfile_path = resolve_path(@basedir, puppetfile)
42
45
  @overrides = overrides
43
46
  @environment = environment
47
+ @module_exclude_regex = module_exclude_regex
44
48
  @environment_name = @environment&.name
45
49
  @default_branch_override = @overrides.dig(:environments, :default_branch_override)
46
50
  @allow_puppetfile_forge = @overrides.dig(:forge, :allow_puppetfile_override)
@@ -68,6 +72,7 @@ module R10K
68
72
  dsl.instance_eval(puppetfile_content(@puppetfile_path), @puppetfile_path)
69
73
 
70
74
  validate_no_duplicate_names(@modules)
75
+ @modules = filter_modules(@modules, @module_exclude_regex) if @module_exclude_regex
71
76
 
72
77
  managed_content = @modules.group_by(&:dirname)
73
78
 
@@ -99,8 +104,11 @@ module R10K
99
104
  @existing_module_versions_by_name = @existing_module_metadata.map {|mod| [ mod.name, mod.version ] }.to_h
100
105
  empty_load_output.merge(modules: @existing_module_metadata)
101
106
 
102
- rescue SyntaxError, LoadError, ArgumentError, NameError => e
107
+ rescue ScriptError, StandardError => e
103
108
  logger.warn _("Unable to preload Puppetfile because of %{msg}" % { msg: e.message })
109
+
110
+ @existing_module_metadata = []
111
+ @existing_module_versions_by_name = {}
104
112
  end
105
113
 
106
114
  def add_module_metadata(name, info)
@@ -157,23 +165,19 @@ module R10K
157
165
  return @modules
158
166
  end
159
167
 
160
- # If this module's metadata has a static version and that version
161
- # matches the existing module declaration use it, otherwise create
162
- # a regular module to sync.
163
- unless mod.version && (mod.version == @existing_module_versions_by_name[mod.name])
164
- mod = mod.to_implementation
168
+ # If this module's metadata has a static version, and that version
169
+ # matches the existing module declaration, and it ostensibly
170
+ # has already has been deployed to disk, use it. Otherwise create a
171
+ # regular module to sync.
172
+ unless mod.version &&
173
+ mod.version == @existing_module_versions_by_name[mod.name] &&
174
+ File.directory?(mod.path)
175
+ mod = mod.to_implementation
165
176
  end
166
177
 
167
178
  @modules << mod
168
179
  end
169
180
 
170
- # @deprecated
171
- # @return [String] The base directory that contains the Puppetfile
172
- def basedir
173
- logger.warn _('"basedir" is deprecated. Please use "environment_name" instead. "basedir" will be removed in a future version.')
174
- @basedir
175
- end
176
-
177
181
  private
178
182
 
179
183
  def empty_load_output
@@ -220,6 +224,10 @@ module R10K
220
224
  return [ install_path, info, spec_deletable ]
221
225
  end
222
226
 
227
+ def filter_modules(modules, exclude_regex)
228
+ modules.reject { |mod| mod.name =~ /#{exclude_regex}/ }
229
+ end
230
+
223
231
  # @param [Array<R10K::Module>] modules
224
232
  def validate_no_duplicate_names(modules)
225
233
  dupes = modules
@@ -72,7 +72,7 @@ class Puppetfile
72
72
  @overrides = options.delete(:overrides) || {}
73
73
  @default_branch_override = @overrides.dig(:environments, :default_branch_override)
74
74
 
75
- @forge = 'forgeapi.puppetlabs.com'
75
+ @forge = 'forgeapi.puppet.com'
76
76
 
77
77
  @loader = ::R10K::ModuleLoader::Puppetfile.new(
78
78
  basedir: @basedir,
@@ -1,3 +1,4 @@
1
+ require 'set'
1
2
  # Defines a collection for application settings
2
3
  #
3
4
  # This implements a hierarchical interface to application settings. Containers