r10k 0.0.9 → 1.0.0rc1

Sign up to get free protection for your applications and to get access to all the features.
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