r10k 0.0.9 → 1.0.0rc1

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 (54) hide show
  1. data/bin/r10k +1 -1
  2. data/lib/r10k.rb +0 -4
  3. data/lib/r10k/cli.rb +9 -5
  4. data/lib/r10k/cli/deploy.rb +108 -0
  5. data/lib/r10k/cli/environment.rb +5 -1
  6. data/lib/r10k/cli/environment/deploy.rb +6 -28
  7. data/lib/r10k/cli/environment/list.rb +6 -10
  8. data/lib/r10k/cli/environment/stale.rb +6 -16
  9. data/lib/r10k/cli/module.rb +5 -1
  10. data/lib/r10k/cli/module/deploy.rb +5 -32
  11. data/lib/r10k/cli/module/list.rb +6 -27
  12. data/lib/r10k/cli/puppetfile.rb +76 -0
  13. data/lib/r10k/cli/synchronize.rb +8 -24
  14. data/lib/r10k/cli/version.rb +22 -0
  15. data/lib/r10k/deployment.rb +55 -26
  16. data/lib/r10k/deployment/config.rb +69 -0
  17. data/lib/r10k/{config → deployment/config}/loader.rb +9 -5
  18. data/lib/r10k/deployment/environment.rb +88 -0
  19. data/lib/r10k/deployment/source.rb +79 -0
  20. data/lib/r10k/errors.rb +3 -5
  21. data/lib/r10k/execution.rb +43 -0
  22. data/lib/r10k/git/cache.rb +131 -0
  23. data/lib/r10k/git/errors.rb +34 -0
  24. data/lib/r10k/git/repository.rb +74 -0
  25. data/lib/r10k/git/working_dir.rb +142 -0
  26. data/lib/r10k/logging.rb +6 -2
  27. data/lib/r10k/module.rb +10 -13
  28. data/lib/r10k/module/forge.rb +35 -22
  29. data/lib/r10k/module/git.rb +18 -8
  30. data/lib/r10k/puppetfile.rb +107 -0
  31. data/lib/r10k/task.rb +13 -0
  32. data/lib/r10k/task/deployment.rb +151 -0
  33. data/lib/r10k/task/environment.rb +29 -0
  34. data/lib/r10k/task/module.rb +18 -0
  35. data/lib/r10k/task/puppetfile.rb +99 -0
  36. data/lib/r10k/task_runner.rb +72 -0
  37. data/lib/r10k/util/purgeable.rb +50 -0
  38. data/lib/r10k/version.rb +1 -1
  39. data/spec/unit/deployment/environment_spec.rb +19 -0
  40. data/spec/unit/git/cache_spec.rb +37 -0
  41. data/spec/unit/git/working_dir_spec.rb +15 -0
  42. data/spec/unit/module/forge_spec.rb +95 -0
  43. data/spec/unit/module_spec.rb +29 -0
  44. metadata +79 -44
  45. data/lib/r10k/action.rb +0 -7
  46. data/lib/r10k/action/environment.rb +0 -74
  47. data/lib/r10k/action/module.rb +0 -36
  48. data/lib/r10k/cli/cache.rb +0 -32
  49. data/lib/r10k/config.rb +0 -46
  50. data/lib/r10k/deployment/environment_collection.rb +0 -75
  51. data/lib/r10k/librarian.rb +0 -31
  52. data/lib/r10k/librarian/dsl.rb +0 -20
  53. data/lib/r10k/root.rb +0 -98
  54. data/lib/r10k/synchro/git.rb +0 -226
@@ -1,8 +1,5 @@
1
- require 'r10k/cli'
2
- require 'r10k/deployment'
3
- require 'r10k/action/environment'
1
+ require 'r10k/cli/deploy'
4
2
 
5
- require 'middleware'
6
3
  require 'cri'
7
4
 
8
5
  module R10K::CLI
@@ -11,30 +8,17 @@ module R10K::CLI
11
8
  @cmd ||= Cri::Command.define do
12
9
  name 'synchronize'
13
10
  usage 'synchronize <options>'
14
- summary 'Fully synchronize all environments'
11
+ summary 'DEPRECATED: Fully synchronize all environments'
15
12
 
16
- run do |opts, args, cmd|
17
- deployment = R10K::Deployment.instance
18
- environments = deployment.environments
19
- directories = (deployment.config[:purgedirs] || [])
20
-
21
- stack = Middleware::Builder.new do
22
- environments.each do |env|
23
- use R10K::Action::Environment::Deploy, env
24
- end
13
+ required :c, :config, 'Specify a configuration file'
25
14
 
26
- directories.each do |dir|
27
- use R10K::Action::Environment::Purge, dir
28
- end
29
- end
15
+ be_hidden
30
16
 
31
- stack_env = {
32
- :update_cache => true,
33
- :trace => opts[:trace],
34
- :recurse => true,
35
- }
17
+ run do |opts, args, cmd|
18
+ logger.warn "#{cmd.name} is deprecated; please use `r10k deploy environment --puppetfile`"
36
19
 
37
- stack.call(stack_env)
20
+ opts.merge!({:puppetfile => true})
21
+ R10K::CLI::Deploy::Environment.command.block.call(opts,args,cmd)
38
22
  end
39
23
  end
40
24
  end
@@ -0,0 +1,22 @@
1
+ require 'r10k/cli'
2
+ require 'r10k/version'
3
+
4
+ require 'cri'
5
+
6
+ module R10K::CLI
7
+ module Version
8
+ def self.command
9
+ @cmd ||= Cri::Command.define do
10
+ name 'version'
11
+ usage 'version'
12
+ summary 'Print the version of r10k'
13
+
14
+ run do |opts, args, cmd|
15
+ puts R10K::VERSION
16
+ exit 0
17
+ end
18
+ end
19
+ end
20
+ end
21
+ self.command.add_command(Version.command)
22
+ end
@@ -1,45 +1,74 @@
1
1
  require 'r10k'
2
- require 'r10k/config'
3
- require 'r10k/synchro/git'
2
+ require 'r10k/deployment/source'
3
+ require 'r10k/deployment/config'
4
+
4
5
  require 'yaml'
5
6
 
6
- class R10K::Deployment
7
+ module R10K
8
+ class Deployment
7
9
  # Model a full installation of module directories and modules.
8
10
 
9
- class << self
10
- def instance
11
- @myself ||= self.new
12
- end
11
+ # Generate a deployment object based on a config
12
+ #
13
+ # @param path [String] The path to the deployment config
14
+ # @return [R10K::Deployment] The deployment loaded with the given config
15
+ def self.load_config(path)
16
+ config = R10K::Deployment::Config.new(path)
17
+ new(config)
18
+ end
13
19
 
14
- def config
15
- instance.config
16
- end
20
+ def initialize(config)
21
+ @config = config
17
22
 
18
- def collection
19
- instance.collection
20
- end
23
+ load_environments
21
24
  end
22
25
 
23
- def initialize
24
- @config = R10K::Config.new
26
+ def fetch_sources
27
+ sources.each do |source|
28
+ source.fetch_remote
29
+ end
30
+ load_environments
25
31
  end
26
32
 
27
- def config
28
- @config
33
+ # Lazily load all sources
34
+ #
35
+ # This instantiates the @_sources instance variable, but should not be
36
+ # used directly as it could be legitimately unset if we're doing lazy
37
+ # loading.
38
+ #
39
+ # @return [Array<R10K::Deployment::Source>] All repository sources
40
+ # specified in the config
41
+ def sources
42
+ load_sources if @_sources.nil?
43
+ @_sources
29
44
  end
30
45
 
31
- # Load up all module roots
46
+ # Lazily load all environments
32
47
  #
33
- # @return [Array<R10K::Root>]
48
+ # This instantiates the @_environments instance variable, but should not be
49
+ # used directly as it could be legitimately unset if we're doing lazy
50
+ # loading.
51
+ #
52
+ # @return [Array<R10K::Deployment::Environment>] All enviroments across
53
+ # all sources
34
54
  def environments
35
- collection.to_a
55
+ load_environments if @_environments.nil?
56
+ @_environments
36
57
  end
37
58
 
38
- def collection
39
- @config.load_config unless @config.loaded?
40
- @collection ||= R10K::Deployment::EnvironmentCollection.new(@config)
41
- @collection
59
+ private
60
+
61
+ def load_sources
62
+ @_sources = @config.setting(:sources).map do |(name, hash)|
63
+ R10K::Deployment::Source.vivify(name, hash)
64
+ end
42
65
  end
43
- end
44
66
 
45
- require 'r10k/deployment/environment_collection'
67
+ def load_environments
68
+ @_environments = []
69
+ sources.each do |source|
70
+ @_environments += source.environments
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,69 @@
1
+ require 'r10k/deployment'
2
+ require 'r10k/deployment/config/loader'
3
+
4
+ module R10K
5
+ class Deployment
6
+ class Config
7
+
8
+ attr_accessor :configfile
9
+
10
+ def initialize(configfile)
11
+ @configfile = configfile
12
+
13
+ load_config
14
+ end
15
+
16
+ # Perform a scan for key and check for both string and symbol keys
17
+ def setting(key)
18
+ keys = [key]
19
+ case key
20
+ when String
21
+ keys << key.to_sym
22
+ when Symbol
23
+ keys << key.to_s
24
+ end
25
+
26
+ # Scan all possible keys to see if the config has a matching value
27
+ keys.inject(nil) do |rv, k|
28
+ require 'pry'; binding.pry
29
+ v = @config[k]
30
+ break v unless v.nil?
31
+ end
32
+ end
33
+
34
+ # Load and store a config file, and set relevant options
35
+ #
36
+ # @param [String] configfile The path to the YAML config file
37
+ def load_config
38
+ if @configfile.nil?
39
+ loader = R10K::Deployment::Config::Loader.new
40
+ @configfile = loader.search
41
+ if @configfile.nil?
42
+ raise ConfigError, "No configuration file given, no config file found in parent directory, and no global config present"
43
+ end
44
+ end
45
+ begin
46
+ @config = YAML.load_file(@configfile)
47
+ apply_config_settings
48
+ rescue => e
49
+ raise ConfigError, "Couldn't load config file: #{e.message}"
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ # Apply config settings to the relevant classes after a config has been loaded.
56
+ #
57
+ # @note this is hack. And gross. And terribad. I am sorry.
58
+ def apply_config_settings
59
+ cachedir = setting(:cachedir)
60
+ if cachedir
61
+ R10K::Git::Cache.cache_root = cachedir
62
+ end
63
+ end
64
+
65
+ class ConfigError < StandardError
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,9 +1,10 @@
1
- require 'r10k'
2
1
 
3
- class R10K::Config
4
- end
5
-
6
- class R10K::Config::Loader
2
+ module R10K
3
+ class Deployment
4
+ class Config
5
+ class Loader
6
+ # Search for a deployment configuration file (r10k.yaml) in all parent
7
+ # directories and in /etc/r10k.yaml
7
8
 
8
9
  def initialize
9
10
  @loadpath = []
@@ -37,3 +38,6 @@ class R10K::Config::Loader
37
38
  @loadpath
38
39
  end
39
40
  end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,88 @@
1
+ require 'r10k/module'
2
+ require 'r10k/logging'
3
+
4
+ module R10K
5
+ class Deployment
6
+ class Environment
7
+
8
+ include R10K::Logging
9
+
10
+ # @!attribute [r] ref
11
+ # The git ref to instantiate into the basedir
12
+ attr_reader :ref
13
+
14
+ # @!attribute [r] remote
15
+ # The location of the remote git repository
16
+ attr_reader :remote
17
+
18
+ # @!attribute [r] basedir
19
+ # The basedir to clone the root into
20
+ attr_reader :basedir
21
+
22
+ # @!attribute [r] dirname
23
+ # @return [String] The directory name to use for the environment
24
+ attr_reader :dirname
25
+
26
+ # @param [String] ref
27
+ # @param [String] remote
28
+ # @param [String] basedir
29
+ # @param [String] dirname The directory to clone the root into, defaults to ref
30
+ def initialize(ref, remote, basedir, dirname = nil)
31
+ @ref = ref
32
+ @remote = remote
33
+ @basedir = basedir
34
+ @dirname = sanitize_dirname(dirname || ref)
35
+
36
+ @working_dir = R10K::Git::WorkingDir.new(@ref, @remote, @basedir, @dirname)
37
+
38
+ @full_path = File.join(@basedir, @dirname)
39
+ end
40
+
41
+ def sync
42
+ recursive_needed = !(@working_dir.cloned?)
43
+ @working_dir.sync
44
+
45
+ if recursive_needed
46
+ logger.debug "Environment #{@full_path} is a fresh clone; automatically updating modules."
47
+ sync_modules
48
+ end
49
+ end
50
+
51
+ def sync_modules
52
+ modules.each do |mod|
53
+ mod.sync
54
+ end
55
+ end
56
+
57
+ def puppetfile
58
+ @puppetfile ||= R10K::Puppetfile.new(@full_path)
59
+ end
60
+
61
+ def modules
62
+ puppetfile.load
63
+ puppetfile.modules
64
+ end
65
+
66
+ private
67
+
68
+ # Strip out non-word characters in an environment directory name
69
+ #
70
+ # Puppet can only use word characers (letter, digit, underscore) in
71
+ # environment names; this cleans up environment names to avoid traversals
72
+ # and similar issues.
73
+ #
74
+ # @param input [String] The raw branch name
75
+ #
76
+ # @return [String] The sanitized branch dirname
77
+ def sanitize_dirname(input)
78
+ output = input.dup
79
+ invalid = %r[\W+]
80
+ if output.gsub!(invalid, '_')
81
+ logger.warn "Environment #{input.inspect} contained non-word characters; sanitizing to #{output.inspect}"
82
+ end
83
+
84
+ output
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,79 @@
1
+ require 'r10k/git/cache'
2
+ require 'r10k/deployment/environment'
3
+ require 'r10k/util/purgeable'
4
+
5
+ module R10K
6
+ class Deployment
7
+ class Source
8
+ # Represents a git repository to map branches to environments
9
+ #
10
+ # This module is backed with a bare git cache that's used to enumerate
11
+ # branches. The cache isn't used for anything else here, but all environments
12
+ # using that remote will be able to reuse the cache.
13
+
14
+ # @!attribute [r] name
15
+ # @return [String] The short name for the deployment source
16
+ attr_reader :name
17
+
18
+ # @!attribute [r] source
19
+ # @return [String] The git remote to use for environments
20
+ attr_reader :remote
21
+
22
+ # @!attribute [r] basedir
23
+ # @return [String] The base directory to deploy the environments into
24
+ attr_reader :basedir
25
+
26
+ # @!attribute [r] environments
27
+ # @return [Array<R10K::Deployment::Environment>] All environments for this source
28
+ attr_reader :environments
29
+
30
+ def self.vivify(name, attrs)
31
+ remote = (attrs.delete(:remote) || attrs.delete('remote'))
32
+ basedir = (attrs.delete(:basedir) || attrs.delete('basedir'))
33
+
34
+ raise ArgumentError, "Unrecognized attributes for #{self.name}: #{attrs.inspect}" unless attrs.empty?
35
+ new(name, remote, basedir)
36
+ end
37
+
38
+ def initialize(name, remote, basedir)
39
+ @name = name
40
+ @remote = remote
41
+ @basedir = basedir
42
+
43
+ @cache = R10K::Git::Cache.new(@remote)
44
+
45
+ load_environments
46
+ end
47
+
48
+ def fetch_remote
49
+ @cache.sync
50
+ load_environments
51
+ end
52
+
53
+ include R10K::Util::Purgeable
54
+
55
+ def managed_directory
56
+ @basedir
57
+ end
58
+
59
+ # List all environments that should exist in the basedir for this source
60
+ # @note This implements a required method for the Purgeable mixin
61
+ # @return [Array<String>]
62
+ def desired_contents
63
+ @environments.map {|env| env.dirname }
64
+ end
65
+
66
+ private
67
+
68
+ def load_environments
69
+ if @cache.cached?
70
+ @environments = @cache.branches.map do |branch|
71
+ R10K::Deployment::Environment.new(branch, @remote, @basedir)
72
+ end
73
+ else
74
+ @environments = []
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
data/lib/r10k/errors.rb CHANGED
@@ -1,7 +1,5 @@
1
- require 'r10k'
2
-
3
1
  module R10K
4
- class ExecutionFailure < Exception
5
- attr_accessor :exit_code, :stdout, :stderr
6
- end
2
+ class ExecutionFailure < StandardError
3
+ attr_accessor :exit_code, :stdout, :stderr
4
+ end
7
5
  end