salt-matrix 0.1.3
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 +7 -0
- data/README.md +21 -0
- data/VERSION +1 -0
- data/bin/salt-matrix +20 -0
- data/lib/salt/formula.rb +36 -0
- data/lib/salt/formula/base.rb +78 -0
- data/lib/salt/formula/git.rb +70 -0
- data/lib/salt/matrix.rb +53 -0
- data/lib/salt/matrix/cli.rb +61 -0
- data/lib/salt/matrix/cli/deploy.rb +20 -0
- data/lib/salt/matrix/error.rb +33 -0
- data/lib/salt/matrix/gitrepo.rb +178 -0
- data/lib/salt/saltfile.rb +77 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 51df135caadd82053d8c9d8f4eb5226e5426d825
|
4
|
+
data.tar.gz: 033cd2406ccbe7bee05e34e7cf726054a270826f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f76d68d5200d533ae6b5d286998576288ab59f13dd983feb5274354411808351d726f2aafd74c5601c5c31ee070bee93c5d34bd9ce49ef7a60c097d2a76c49ad
|
7
|
+
data.tar.gz: cb7a5067e537d25d145bb3cab44779cfb57e0c97a090642b8d752b3c8f63e5ecb9199b1d444c8bc724c1fc840ed215f5ba0b857b7f96b0e5f4fb67b9d5a2e8db
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
salt-matrix
|
2
|
+
===========
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
File Format
|
7
|
+
-----------
|
8
|
+
|
9
|
+
Saltfile
|
10
|
+
|
11
|
+
```
|
12
|
+
|
13
|
+
formula 'custom_grains', :git => 'http://stash.service.audsci.net/scm/salt/custom_grains-formula.git', '0.1.0'
|
14
|
+
|
15
|
+
formula 'custom_grains', :git => 'http://stash.service.audsci.net/scm/salt/custom_grains-formula.git', :branch => 'master'
|
16
|
+
|
17
|
+
formula 'custom_grains', :git => 'http://stash.service.audsci.net/scm/salt/custom_grains-formula.git', :tag => 'this_rel'
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
```
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.3
|
data/bin/salt-matrix
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path('../../lib', __FILE__)
|
4
|
+
$LOAD_PATH << lib unless $LOAD_PATH.include? lib
|
5
|
+
|
6
|
+
require 'colorize'
|
7
|
+
require 'salt/matrix'
|
8
|
+
|
9
|
+
|
10
|
+
begin
|
11
|
+
cli = Salt::Matrix::Cli.start
|
12
|
+
rescue Interrupt
|
13
|
+
exit(1)
|
14
|
+
rescue SystemExit => e
|
15
|
+
exit(e.status)
|
16
|
+
rescue Exception => e
|
17
|
+
$stderr.puts "\nUnhandled exception: #{e.inspect}".red
|
18
|
+
$stderr.puts e.backtrace.join("\n")
|
19
|
+
exit(1)
|
20
|
+
end
|
data/lib/salt/formula.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Salt
|
4
|
+
module Formula
|
5
|
+
|
6
|
+
# Register an module implementation for later generation
|
7
|
+
def self.register(klass)
|
8
|
+
@klasses ||= []
|
9
|
+
@klasses << klass
|
10
|
+
end
|
11
|
+
|
12
|
+
# Look up the implementing class and instantiate an object
|
13
|
+
#
|
14
|
+
# This method takes the arguments for normal object generation and checks all
|
15
|
+
# inheriting classes to see if they implement the behavior needed to create
|
16
|
+
# the requested object. It selects the first class that can implement an object
|
17
|
+
# with `name, args`, and generates an object of that class.
|
18
|
+
#
|
19
|
+
# @param [String] name The unique name of the module
|
20
|
+
# @param [String] basedir The root to install the module in
|
21
|
+
# @param [Object] args An arbitary value or set of values that specifies the implementation
|
22
|
+
#
|
23
|
+
# @return [Object < R10K::Module] A member of the implementing subclass
|
24
|
+
def self.new(name, basedir, args)
|
25
|
+
if implementation = @klasses.find { |klass| klass.implement?(name, args) }
|
26
|
+
obj = implementation.new(name, basedir, args)
|
27
|
+
obj
|
28
|
+
else
|
29
|
+
raise "Module #{name} with args #{args.inspect} doesn't have an implementation. (Are you using the right arguments?)"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'salt/formula/base'
|
34
|
+
require 'salt/formula/git'
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
require 'salt/formula'
|
3
|
+
|
4
|
+
|
5
|
+
# This class defines a common interface for module implementations.
|
6
|
+
class Salt::Formula::Base
|
7
|
+
|
8
|
+
# @!attribute [r] name
|
9
|
+
# @return [String] The name of the module
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# @param [r] dirname
|
13
|
+
# @return [String] The name of the directory containing this module
|
14
|
+
attr_reader :dirname
|
15
|
+
|
16
|
+
# @deprecated
|
17
|
+
alias :basedir :dirname
|
18
|
+
|
19
|
+
# @!attribute [r] path
|
20
|
+
# @return [Pathname] The full path of the module
|
21
|
+
attr_reader :path
|
22
|
+
|
23
|
+
# @param title [String]
|
24
|
+
# @param dirname [String]
|
25
|
+
# @param args [Array]
|
26
|
+
def initialize(name, dirname, args)
|
27
|
+
@name = name
|
28
|
+
@dirname = dirname
|
29
|
+
@args = args
|
30
|
+
@path = Pathname.new(File.join(@dirname, @name))
|
31
|
+
end
|
32
|
+
|
33
|
+
# @deprecated
|
34
|
+
# @return [String] The full filesystem path to the module.
|
35
|
+
def full_path
|
36
|
+
path.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
# Synchronize this module with the indicated state.
|
40
|
+
# @abstract
|
41
|
+
def sync
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the desired version of this module
|
46
|
+
# @abstract
|
47
|
+
def version
|
48
|
+
raise NotImplementedError
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return the status of the currently installed module.
|
52
|
+
#
|
53
|
+
# This can return the following values:
|
54
|
+
#
|
55
|
+
# * :absent - there is no module installed
|
56
|
+
# * :mismatched - there is a module installed but it must be removed and reinstalled
|
57
|
+
# * :outdated - the correct module is installed but it needs to be updated
|
58
|
+
# * :insync - the correct module is installed and up to date, or the module is actually a boy band.
|
59
|
+
#
|
60
|
+
# @return [Symbol]
|
61
|
+
# @abstract
|
62
|
+
def status
|
63
|
+
raise NotImplementedError
|
64
|
+
end
|
65
|
+
|
66
|
+
def accept(visitor)
|
67
|
+
visitor.visit(:module, self)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return the properties of the module
|
71
|
+
#
|
72
|
+
# @return [Hash]
|
73
|
+
# @abstract
|
74
|
+
def properties
|
75
|
+
raise NotImplementedError
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'salt/formula'
|
2
|
+
require 'salt/matrix/gitrepo'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
class Salt::Formula::Git < Salt::Formula::Base
|
6
|
+
|
7
|
+
Salt::Formula.register(self)
|
8
|
+
|
9
|
+
def self.implement?(name, args)
|
10
|
+
args.is_a? Hash and (args.has_key?(:git) or args.has_key?(:github))
|
11
|
+
rescue
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
# @!attribute [r] repo
|
16
|
+
# @api private
|
17
|
+
# @return [Salt::Matrix::Gitrepo]
|
18
|
+
attr_reader :repo
|
19
|
+
|
20
|
+
def initialize(name, dirname, args)
|
21
|
+
super
|
22
|
+
parse_options(@args)
|
23
|
+
@name = name
|
24
|
+
@repo = Salt::Matrix::Gitrepo.new(@remote, @name, @ref, dirname)
|
25
|
+
end
|
26
|
+
|
27
|
+
def version
|
28
|
+
@ref
|
29
|
+
end
|
30
|
+
|
31
|
+
def properties
|
32
|
+
{
|
33
|
+
:expected => @ref,
|
34
|
+
:actual => (@repo.head || "(unresolvable)"),
|
35
|
+
:type => :git,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
extend Forwardable
|
40
|
+
|
41
|
+
def_delegators :@repo, :sync, :status
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def parse_options(options)
|
46
|
+
@remote = options.delete(:git) || options.delete(:github)
|
47
|
+
|
48
|
+
if options[:branch]
|
49
|
+
@ref = "origin/#{options.delete(:branch)}"
|
50
|
+
end
|
51
|
+
|
52
|
+
if options[:tag]
|
53
|
+
@ref = options.delete(:tag)
|
54
|
+
end
|
55
|
+
|
56
|
+
if options[:commit]
|
57
|
+
@ref = options.delete(:commit)
|
58
|
+
end
|
59
|
+
|
60
|
+
if options[:ref]
|
61
|
+
@ref = options.delete(:ref)
|
62
|
+
end
|
63
|
+
|
64
|
+
@ref ||= 'master'
|
65
|
+
|
66
|
+
unless options.empty?
|
67
|
+
raise ArgumentError, "Unhandled options #{options.keys.inspect} specified for #{self.class}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/salt/matrix.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
require 'singleton'
|
3
|
+
require 'version'
|
4
|
+
require 'salt/saltfile'
|
5
|
+
require 'salt/matrix/error'
|
6
|
+
|
7
|
+
|
8
|
+
module Salt
|
9
|
+
|
10
|
+
class Matrix
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
autoload :Cli, 'salt/matrix/cli'
|
14
|
+
|
15
|
+
attr_reader :debug
|
16
|
+
|
17
|
+
is_versioned
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@debug_buf = []
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def set_debug
|
25
|
+
@debug = true
|
26
|
+
unless @debug_buf.empty?
|
27
|
+
debug {|fh| @debug_buf.each {|m| fh.write "#{m}\n" }}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.set_debug
|
32
|
+
self.instance.set_debug
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def debug(msg, &block)
|
37
|
+
if block_given?
|
38
|
+
yield $stdout
|
39
|
+
elsif @debug
|
40
|
+
puts "*** #{msg}"
|
41
|
+
else
|
42
|
+
# just in case we turn debug on in a bit.
|
43
|
+
@debug_buf << msg
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.debug(msg, &block)
|
48
|
+
self.instance.debug(msg, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
|
5
|
+
module Salt
|
6
|
+
class Matrix
|
7
|
+
class Cli < Thor
|
8
|
+
|
9
|
+
autoload :Deploy, 'salt/matrix/cli/deploy'
|
10
|
+
|
11
|
+
|
12
|
+
#class_option :trace, :type => :boolean
|
13
|
+
|
14
|
+
|
15
|
+
desc 'version', 'Display version information'
|
16
|
+
def version
|
17
|
+
puts Salt::Matrix::VERSION
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'deploy', 'Deploy an environment from Saltfile'
|
21
|
+
long_desc <<-LONGDESC
|
22
|
+
Process a Saltfile and build an environment from the formulas
|
23
|
+
specified within the file. Saltfile consists of one or more entries
|
24
|
+
of the form:
|
25
|
+
\n
|
26
|
+
formula 'NAME', ARG, ARG, ARG ...
|
27
|
+
\n
|
28
|
+
NAME is the formula name which will be the directory name that
|
29
|
+
contains the formula. ARGs will vary depending upon the location
|
30
|
+
of the formula. Generally the ARGs will consist of the key :git set
|
31
|
+
to the location of the Git repository for the formula and a refernce
|
32
|
+
to the Git tag, branch or commit ID.
|
33
|
+
\n
|
34
|
+
With the --dir option, one may specify another directory other than
|
35
|
+
the current working directory to find the Saltfile.
|
36
|
+
LONGDESC
|
37
|
+
option :dir, :default => '.'
|
38
|
+
option :debug, :default => false
|
39
|
+
def deploy
|
40
|
+
if options['debug']
|
41
|
+
Salt::Master.set_debug
|
42
|
+
end
|
43
|
+
deploy_dir = File.expand_path options['dir']
|
44
|
+
Salt::Matrix.debug "Deployment directory set to #{deploy_dir}"
|
45
|
+
saltfile = Salt::Saltfile.new deploy_dir
|
46
|
+
saltfile.load
|
47
|
+
saltfile.formulas.each do |f|
|
48
|
+
f.sync
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
desc 'foo', 'Throw an exception'
|
54
|
+
def foo
|
55
|
+
raise RuntimeError, 'This is foo'
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Salt
|
4
|
+
class Matrix
|
5
|
+
|
6
|
+
class Error < StandardError
|
7
|
+
|
8
|
+
attr_accessor :original
|
9
|
+
|
10
|
+
def self.wrap(original, mesg, options = {})
|
11
|
+
new(mesg, options).tap do |e|
|
12
|
+
e.set_backtrace(caller(4))
|
13
|
+
e.original = original
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def initialize(mesg, options = {})
|
19
|
+
super(mesg)
|
20
|
+
|
21
|
+
bt = options.delete(:backtrace)
|
22
|
+
if bt
|
23
|
+
set_backtrace(bt)
|
24
|
+
end
|
25
|
+
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
|
2
|
+
require 'fileutils'
|
3
|
+
require 'yaml'
|
4
|
+
require 'git'
|
5
|
+
|
6
|
+
|
7
|
+
module Salt
|
8
|
+
class Matrix
|
9
|
+
|
10
|
+
##
|
11
|
+
# Gitrepo class provides the low level interface to a Git repository.
|
12
|
+
|
13
|
+
class Gitrepo
|
14
|
+
|
15
|
+
def initialize(remote, name, ref, dirname)
|
16
|
+
@ref = ref
|
17
|
+
@remote = remote
|
18
|
+
@dirname = dirname
|
19
|
+
@formuladir = File.join(dirname, name)
|
20
|
+
@repodir = File.join(dirname, '.cache', name)
|
21
|
+
@name = name
|
22
|
+
|
23
|
+
# Grab the last settings if they exist.
|
24
|
+
@settings = {}
|
25
|
+
if File.exist? "#{@formuladir}/.salt-matrix.yaml"
|
26
|
+
@settings = YAML.load_file("#{@formuladir}/.salt-matrix.yaml")
|
27
|
+
end
|
28
|
+
|
29
|
+
@git = nil
|
30
|
+
if Dir.exist? @repodir
|
31
|
+
@git = Git.open @repodir
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def sync
|
37
|
+
|
38
|
+
case status
|
39
|
+
when :absent
|
40
|
+
puts "#{"%-30s" % @name}" + "Cloning".yellow
|
41
|
+
replicate_repo
|
42
|
+
puts "#{"%-30s" % @name}" + "Syncing".cyan
|
43
|
+
replicate_formula
|
44
|
+
when :mismatched
|
45
|
+
puts "#{"%-30s" % @name}" + "Syncing".cyan
|
46
|
+
replicate_formula
|
47
|
+
when :badrepo
|
48
|
+
puts "#{"%-30s" % @name}" + "Kill repo".yellow
|
49
|
+
destroy_repo
|
50
|
+
puts "#{"%-30s" % @name}" + "Kill formula".yellow
|
51
|
+
destroy_formula
|
52
|
+
puts "#{"%-30s" % @name}" + "Cloning".yellow
|
53
|
+
replicate_repo
|
54
|
+
puts "#{"%-30s" % @name}" + "Syncing".cyan
|
55
|
+
replicate_formula
|
56
|
+
when :outdated
|
57
|
+
puts "#{"%-30s" % @name}" + "Updating repo".cyan
|
58
|
+
update_repo
|
59
|
+
puts "#{"%-30s" % @name}" + "Syncing".cyan
|
60
|
+
replicate_formula
|
61
|
+
when :insync
|
62
|
+
puts "#{"%-30s" % @name}" + "OK".green
|
63
|
+
else
|
64
|
+
puts "#{"%-30s" % @name}" + "Invalid State".red
|
65
|
+
end
|
66
|
+
|
67
|
+
save_settings
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def status
|
72
|
+
# Reported conditions:
|
73
|
+
#
|
74
|
+
# :absent Nothing currently exists
|
75
|
+
# :mismatched Formula is not derived from repo
|
76
|
+
# :badrepo Cloned repo is not what is specified
|
77
|
+
# :outdated Expected, but needs to be sync'ed
|
78
|
+
# :insync Expected and upto date
|
79
|
+
|
80
|
+
if !Dir.exist? @formuladir or !Dir.exist? @repodir
|
81
|
+
return :absent
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
if @settings.empty?
|
87
|
+
return :mismatched
|
88
|
+
elsif @settings[:remote] != @remote
|
89
|
+
return :badrepo
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check the repo settings
|
93
|
+
unless @git.nil?
|
94
|
+
@git.fetch
|
95
|
+
if @settings[:remote] != @git.remote.url
|
96
|
+
return :badrepo
|
97
|
+
elsif @settings[:sha] != @git.object(@ref).sha
|
98
|
+
return :outdated
|
99
|
+
else
|
100
|
+
return :insync
|
101
|
+
end
|
102
|
+
else
|
103
|
+
# Ideally this should never get returned!
|
104
|
+
return :invalid
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def destroy_repo
|
113
|
+
FileUtils.rm_r @repodir
|
114
|
+
@git = nil
|
115
|
+
end
|
116
|
+
|
117
|
+
def destroy_formula
|
118
|
+
FileUtils.rm_r @formuladir
|
119
|
+
end
|
120
|
+
|
121
|
+
def replicate_repo
|
122
|
+
unless Dir.exists? "#{@dirname}/.cache"
|
123
|
+
Dir.mkdir "#{@dirname}/.cache"
|
124
|
+
end
|
125
|
+
|
126
|
+
# clone to the .cache directory
|
127
|
+
Dir.chdir "#{@dirname}/.cache"
|
128
|
+
begin
|
129
|
+
if @git.nil?
|
130
|
+
Salt::Matrix.debug "Cloning: #{@remote}"
|
131
|
+
@git = Git.clone(@remote, @name)
|
132
|
+
end
|
133
|
+
rescue Exception => e
|
134
|
+
puts "Exception: #{e}"
|
135
|
+
puts e.backtrace.join("\n")
|
136
|
+
puts e.inspect
|
137
|
+
end
|
138
|
+
|
139
|
+
# Checkout to the correct revsion
|
140
|
+
Salt::Matrix.debug "Checking out: #{@ref}"
|
141
|
+
@git.checkout @ref
|
142
|
+
|
143
|
+
# Record the Git ID
|
144
|
+
@settings[:sha] = @git.object("HEAD").sha
|
145
|
+
end
|
146
|
+
|
147
|
+
def update_repo
|
148
|
+
@git.fetch
|
149
|
+
@git.pull
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def replicate_formula
|
154
|
+
# Locate the formula directory and copy it
|
155
|
+
# for now we treat the name as the formula directory name
|
156
|
+
if Dir.exist? File.join(@repodir, @name)
|
157
|
+
system("rsync -a --delete --exclude .salt-matrix.yaml #{File.join(@repodir, @name)} #{@dirname}")
|
158
|
+
#FileUtils.cp_r(File.join(@repodir, @name), @dirname)
|
159
|
+
@settings[:name] = @name
|
160
|
+
@settings[:remote] = @remote
|
161
|
+
@settings[:ref] = @ref
|
162
|
+
else
|
163
|
+
puts "#{"%-30s" % @name}" + "Invalid formula".red
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
def save_settings
|
169
|
+
if Dir.exist? @formuladir
|
170
|
+
File.open("#{@formuladir}/.salt-matrix.yaml", 'w') do |fh|
|
171
|
+
fh.write @settings.to_yaml
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
require 'salt/formula'
|
3
|
+
|
4
|
+
module Salt
|
5
|
+
|
6
|
+
class Saltfile
|
7
|
+
|
8
|
+
attr_reader :basedir
|
9
|
+
attr_reader :formuladir
|
10
|
+
attr_reader :formulas
|
11
|
+
attr_reader :saltfile
|
12
|
+
|
13
|
+
# @param [String] basedir
|
14
|
+
# @param [String] formuladir
|
15
|
+
# @param [String] saltfile
|
16
|
+
def initialize(basedir='.', formuladir=nil, saltfile=nil)
|
17
|
+
@basedir = basedir
|
18
|
+
@formuladir = formuladir || @basedir
|
19
|
+
@saltfile = saltfile || File.join(@basedir, 'Saltfile')
|
20
|
+
|
21
|
+
@formulas = []
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def load
|
26
|
+
if File.readable? @saltfile
|
27
|
+
self.load!
|
28
|
+
else
|
29
|
+
$stderr.puts "Saltfile (#{@saltfile}) missing or unreadable"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def load!
|
35
|
+
dsl = DSL.new(self)
|
36
|
+
dsl.instance_eval(saltfile_contents, @saltfile)
|
37
|
+
rescue SyntaxError, LoadError => e
|
38
|
+
puts e.inspect.magenta
|
39
|
+
raise Salt::Matrix::Error.wrap(e, "Failed to process #{@saltfile}")
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# @param [String] name
|
44
|
+
# @param [*Object] args
|
45
|
+
def add_formula(name, args)
|
46
|
+
@formulas << Salt::Formula.new(name, @formuladir, args)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [File]
|
50
|
+
def saltfile_contents
|
51
|
+
File.read(@saltfile)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
class DSL
|
57
|
+
|
58
|
+
# @param [*Object] librarian
|
59
|
+
def initialize(librarian)
|
60
|
+
@librarian = librarian
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param [String] name
|
64
|
+
# @param [*Object] args
|
65
|
+
def formula(name, args=nil)
|
66
|
+
@librarian.add_formula(name, args)
|
67
|
+
end
|
68
|
+
|
69
|
+
def method_missing(methods, *args)
|
70
|
+
raise NoMethodError, "unrecognized declaration: #{method}"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: salt-matrix
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gerard Hickey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
- - '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 10.4.0
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '10.4'
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 10.4.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: thor
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.19.1
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.19.1
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: colorize
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.7.5
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.7.5
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: version
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.0'
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.0.0
|
85
|
+
type: :runtime
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ~>
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '1.0'
|
92
|
+
- - '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.0.0
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: git
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.2.0
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ~>
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 1.2.0
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rspec
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ~>
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '3.1'
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 3.1.0
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.1'
|
126
|
+
- - '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 3.1.0
|
129
|
+
description: Tool to build salt environments from various sources
|
130
|
+
email: gerard.hickey@audiencescience.com
|
131
|
+
executables:
|
132
|
+
- salt-matrix
|
133
|
+
extensions: []
|
134
|
+
extra_rdoc_files: []
|
135
|
+
files:
|
136
|
+
- README.md
|
137
|
+
- VERSION
|
138
|
+
- bin/salt-matrix
|
139
|
+
- lib/salt/formula.rb
|
140
|
+
- lib/salt/formula/base.rb
|
141
|
+
- lib/salt/formula/git.rb
|
142
|
+
- lib/salt/matrix.rb
|
143
|
+
- lib/salt/matrix/cli.rb
|
144
|
+
- lib/salt/matrix/cli/deploy.rb
|
145
|
+
- lib/salt/matrix/error.rb
|
146
|
+
- lib/salt/matrix/gitrepo.rb
|
147
|
+
- lib/salt/saltfile.rb
|
148
|
+
homepage: http://stash.service.audsci.net/projects/SALT/repos/salt-matrix/
|
149
|
+
licenses:
|
150
|
+
- Apache-2.0
|
151
|
+
metadata: {}
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - '>='
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 1.9.3
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubyforge_project:
|
168
|
+
rubygems_version: 2.2.2
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: Tool to build salt environments
|
172
|
+
test_files: []
|