bixby-provision 0.1.0
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/Gemfile +29 -0
- data/Gemfile.lock +192 -0
- data/Rakefile +13 -0
- data/VERSION +1 -0
- data/Vagrantfile +64 -0
- data/bin/bixby-provision +6 -0
- data/bixby-provision.gemspec +113 -0
- data/lib/bixby-provision.rb +2 -0
- data/lib/bixby/provision.rb +65 -0
- data/lib/bixby/provision/app.rb +34 -0
- data/lib/bixby/provision/dsl.rb +23 -0
- data/lib/bixby/provision/dsl/base.rb +76 -0
- data/lib/bixby/provision/dsl/bundler.rb +18 -0
- data/lib/bixby/provision/dsl/config.rb +124 -0
- data/lib/bixby/provision/dsl/dir.rb +34 -0
- data/lib/bixby/provision/dsl/file.rb +108 -0
- data/lib/bixby/provision/dsl/inventory.rb +18 -0
- data/lib/bixby/provision/dsl/meteor.rb +30 -0
- data/lib/bixby/provision/dsl/nodejs.rb +73 -0
- data/lib/bixby/provision/dsl/npm.rb +18 -0
- data/lib/bixby/provision/dsl/ntp.rb +41 -0
- data/lib/bixby/provision/dsl/packager/apt.rb +46 -0
- data/lib/bixby/provision/dsl/packager/base.rb +11 -0
- data/lib/bixby/provision/dsl/packager/npm.rb +67 -0
- data/lib/bixby/provision/dsl/packager/yum.rb +100 -0
- data/lib/bixby/provision/dsl/packager/yum/epel.rb +71 -0
- data/lib/bixby/provision/dsl/packager/yum/mongodb.rb +43 -0
- data/lib/bixby/provision/dsl/ruby.rb +21 -0
- data/lib/bixby/provision/dsl/run_control.rb +49 -0
- data/lib/bixby/provision/dsl/scm.rb +34 -0
- data/lib/bixby/provision/dsl/scm/base.rb +11 -0
- data/lib/bixby/provision/dsl/scm/git.rb +89 -0
- data/lib/bixby/provision/dsl/scm/svn.rb +11 -0
- data/lib/bixby/provision/dsl/service.rb +56 -0
- data/lib/bixby/provision/dsl/services/base.rb +11 -0
- data/lib/bixby/provision/dsl/services/init.rb +40 -0
- data/lib/bixby/provision/dsl/system.rb +53 -0
- data/lib/bixby/provision/dsl/util/file.rb +100 -0
- data/lib/bixby/provision/dsl/variable.rb +27 -0
- data/lib/bixby/provision/manifest.rb +49 -0
- data/lib/bixby/provision/manifest/dsl_proxy.rb +17 -0
- data/manifest.rb +31 -0
- data/tasks/coverage.rake +2 -0
- data/tasks/jeweler.rake +21 -0
- data/tasks/test.rake +5 -0
- data/tasks/yard.rake +2 -0
- metadata +244 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
|
5
|
+
class App
|
6
|
+
|
7
|
+
include Bixby::ScriptUtil
|
8
|
+
include Bixby::Log
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
end
|
12
|
+
|
13
|
+
def run!
|
14
|
+
file = ARGV.shift
|
15
|
+
|
16
|
+
if file == "--" then
|
17
|
+
logger.info "reading manifest on STDIN"
|
18
|
+
str = read_stdin()
|
19
|
+
t = Tempfile.new("bixby-provision-")
|
20
|
+
t.write(str)
|
21
|
+
t.close
|
22
|
+
file = t.path
|
23
|
+
else
|
24
|
+
file = File.expand_path(file)
|
25
|
+
logger.info "reading manifest from file #{file}"
|
26
|
+
end
|
27
|
+
|
28
|
+
Bixby::Provision::Manifest.new(file)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
require "semver"
|
3
|
+
|
4
|
+
require "bixby/provision/dsl/base"
|
5
|
+
require "bixby/provision/dsl/run_control"
|
6
|
+
require "bixby/provision/dsl/variable"
|
7
|
+
require "bixby/provision/dsl/config"
|
8
|
+
|
9
|
+
require "bixby/provision/dsl/system"
|
10
|
+
require "bixby/provision/dsl/service"
|
11
|
+
|
12
|
+
require "bixby/provision/dsl/file"
|
13
|
+
require "bixby/provision/dsl/dir"
|
14
|
+
require "bixby/provision/dsl/scm"
|
15
|
+
|
16
|
+
require "bixby/provision/dsl/inventory"
|
17
|
+
|
18
|
+
require "bixby/provision/dsl/ntp"
|
19
|
+
require "bixby/provision/dsl/nodejs"
|
20
|
+
require "bixby/provision/dsl/npm"
|
21
|
+
require "bixby/provision/dsl/meteor"
|
22
|
+
require "bixby/provision/dsl/ruby"
|
23
|
+
require "bixby/provision/dsl/bundler"
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
require "bixby/provision/dsl/util/file"
|
3
|
+
|
4
|
+
module Bixby
|
5
|
+
module Provision
|
6
|
+
|
7
|
+
class Base
|
8
|
+
|
9
|
+
include Bixby::Log
|
10
|
+
extend Bixby::Log
|
11
|
+
include Bixby::ScriptUtil
|
12
|
+
include Bixby::Provision::Util::File
|
13
|
+
|
14
|
+
PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
15
|
+
|
16
|
+
attr_accessor :manifest, :proxy
|
17
|
+
|
18
|
+
def initialize(obj=nil)
|
19
|
+
if obj.kind_of? Base then
|
20
|
+
@manifest = obj.manifest
|
21
|
+
@proxy = obj.proxy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def tap(&block)
|
26
|
+
self.instance_eval(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_uid(user)
|
30
|
+
return user if user.nil? or user.kind_of? Fixnum
|
31
|
+
return user.to_i if user =~ /^[0-9]+$/ # convert to int, e.g. "500"
|
32
|
+
begin
|
33
|
+
return Etc.getpwnam(user).uid
|
34
|
+
rescue ArgumentError => ex
|
35
|
+
# TODO raise
|
36
|
+
logger.warn("Username '#{user}' was invalid: #{ex.message}")
|
37
|
+
end
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_user(uid)
|
42
|
+
begin
|
43
|
+
return Etc.getpwuid(uid).name
|
44
|
+
rescue ArgumentError => ex
|
45
|
+
# TODO raise
|
46
|
+
logger.warn("Username '#{user}' was invalid: #{ex.message}")
|
47
|
+
end
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_gid(group)
|
52
|
+
return group if group.nil? or group.kind_of? Fixnum
|
53
|
+
return group.to_i if group =~ /^[0-9]+$/ # convert to int, e.g. "500"
|
54
|
+
begin
|
55
|
+
return Etc.getgrnam(group).gid
|
56
|
+
rescue ArgumentError => ex
|
57
|
+
# TODO raise
|
58
|
+
logger.warn("Group '#{group}' was invalid: #{ex.message}")
|
59
|
+
end
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_group(gid)
|
64
|
+
begin
|
65
|
+
return Etc.getgrgid(gid).name
|
66
|
+
rescue ArgumentError => ex
|
67
|
+
# TODO raise
|
68
|
+
logger.warn("Group '#{group}' was invalid: #{ex.message}")
|
69
|
+
end
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
require "tilt"
|
3
|
+
|
4
|
+
module Bixby
|
5
|
+
module Provision
|
6
|
+
|
7
|
+
class Config < Base
|
8
|
+
|
9
|
+
EXPORTS = []
|
10
|
+
|
11
|
+
def file(dest, opts={})
|
12
|
+
|
13
|
+
# By default, attempt to preserve ownership and mode if none are given in opts
|
14
|
+
opts[:preserve] = true if !opts.include? :preserve
|
15
|
+
|
16
|
+
dest_file = File.expand_path(dest)
|
17
|
+
if File.exists? dest_file then
|
18
|
+
stat = File.stat(dest_file)
|
19
|
+
old_owner = "#{stat.uid}:#{stat.gid}"
|
20
|
+
old_mode = stat.mode
|
21
|
+
else
|
22
|
+
old_owner = old_mode = nil
|
23
|
+
dir.create(File.dirname(dest_file))
|
24
|
+
end
|
25
|
+
|
26
|
+
source = resolve_file(opts.delete(:source), dest_file)
|
27
|
+
if source.nil? then
|
28
|
+
# TODO raise
|
29
|
+
end
|
30
|
+
|
31
|
+
template = get_template(source)
|
32
|
+
if template.nil? then
|
33
|
+
|
34
|
+
if sha256sum(dest_file) == sha256sum(source) then
|
35
|
+
logger.info "[config] skipping #{dest_file}: sha256sum matches"
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
# just copy the file over
|
40
|
+
if File.writable?(dest_file) then
|
41
|
+
logger.info "[config] copying #{source} to #{dest}"
|
42
|
+
FileUtils.cp(source, dest_file)
|
43
|
+
else
|
44
|
+
logger.info "[config] copying #{source} to #{dest} (as root)"
|
45
|
+
logged_sudo("cp #{source} #{dest_file}")
|
46
|
+
end
|
47
|
+
|
48
|
+
else
|
49
|
+
# use template
|
50
|
+
logger.info "[config] rendering template #{source}"
|
51
|
+
str = template.render(self.proxy)
|
52
|
+
|
53
|
+
if (File.exists? dest_file and File.writable? dest_file) or
|
54
|
+
File.writable? File.dirname(dest_file) then
|
55
|
+
|
56
|
+
# write directly
|
57
|
+
File.open(dest_file, 'w') { |f| f.write str }
|
58
|
+
|
59
|
+
else
|
60
|
+
# write to temp and mv into place
|
61
|
+
t = Tempfile.new("bixby-provision-")
|
62
|
+
t.write str
|
63
|
+
t.close
|
64
|
+
logged_sudo("mv #{t.path} #{dest_file}")
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# set correct ownership/mode
|
70
|
+
owner = opts[:chown]
|
71
|
+
mode = opts[:chmod]
|
72
|
+
if opts[:preserve] then
|
73
|
+
owner ||= old_owner
|
74
|
+
mode ||= old_mode
|
75
|
+
end
|
76
|
+
chown(dest_file, owner)
|
77
|
+
chmod(dest_file, mode)
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def get_template(file)
|
85
|
+
return nil if File.basename(file) !~ /\..*$/
|
86
|
+
begin
|
87
|
+
return Tilt.new(file)
|
88
|
+
rescue RuntimeError => ex
|
89
|
+
if ex.message =~ /No template engine registered/ then
|
90
|
+
return nil
|
91
|
+
end
|
92
|
+
raise ex
|
93
|
+
end
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def resolve_file(file, dest)
|
98
|
+
if file.nil? then
|
99
|
+
return nil if dest.nil?
|
100
|
+
# look for a file with the same name as in dest
|
101
|
+
file = File.basename(dest)
|
102
|
+
end
|
103
|
+
|
104
|
+
f = File.expand_path(file)
|
105
|
+
return f if File.exists? f
|
106
|
+
|
107
|
+
# search for it in file/
|
108
|
+
f = File.expand_path("../files/#{file}", self.manifest.filename)
|
109
|
+
return f if File.exists? f
|
110
|
+
|
111
|
+
# look for the given file with any extension
|
112
|
+
files = Dir.glob("#{f}.*")
|
113
|
+
return files.shift if files.size == 1
|
114
|
+
|
115
|
+
return nil
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
register_dsl Config
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
|
5
|
+
class DirDSL < Base
|
6
|
+
|
7
|
+
EXPORTS = [:mkdir, :mkdir_p]
|
8
|
+
|
9
|
+
def create(path, opts={})
|
10
|
+
logger.info "[dir] ensuring #{path} exists"
|
11
|
+
path = File.expand_path(path)
|
12
|
+
begin
|
13
|
+
FileUtils.mkdir_p(path) if !File.exists? path
|
14
|
+
chown(path, opts[:chown])
|
15
|
+
chmod(path, opts[:chmod])
|
16
|
+
rescue Errno::EACCES => ex
|
17
|
+
logger.info "[dir] permission denied, trying again with sudo"
|
18
|
+
logged_sudo("mkdir -p #{path}")
|
19
|
+
chown(path, opts[:chown])
|
20
|
+
chmod(path, opts[:chmod])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
alias_method :mkdir, :create
|
24
|
+
alias_method :mkdir_p, :create
|
25
|
+
|
26
|
+
def recreate(path, opts={})
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
register_dsl DirDSL, "dir"
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
|
5
|
+
class FileDSL < Base
|
6
|
+
|
7
|
+
EXPORTS = [:symlink, :copy, :cp]
|
8
|
+
|
9
|
+
def create(opts={})
|
10
|
+
end
|
11
|
+
|
12
|
+
def symlink(source, dest)
|
13
|
+
source = File.expand_path(source)
|
14
|
+
dest = File.expand_path(dest)
|
15
|
+
|
16
|
+
if File.symlink?(dest) && File.realpath(dest) == source then
|
17
|
+
logger.info "[file] #{dest} already points to #{source}"
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
logger.info "[file] creating symlink: #{dest} -> #{source}"
|
22
|
+
|
23
|
+
if File.writable? File.dirname(dest) then
|
24
|
+
FileUtils.symlink(source, dest)
|
25
|
+
else
|
26
|
+
# as root
|
27
|
+
logged_sudo("ln -sf #{source} #{dest}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def copy(*args)
|
32
|
+
if args.last.kind_of? Hash then
|
33
|
+
opts = args.pop
|
34
|
+
else
|
35
|
+
opts = {}
|
36
|
+
end
|
37
|
+
|
38
|
+
dest = File.expand_path(args.pop)
|
39
|
+
if args.length > 1 || args.first.include?("*") then
|
40
|
+
dest_dir = dest
|
41
|
+
self.dir.mkdir(dest_dir)
|
42
|
+
elsif File.directory? dest then
|
43
|
+
dest_dir = dest
|
44
|
+
else
|
45
|
+
dest_dir = File.dirname(dest)
|
46
|
+
self.dir.mkdir(dest_dir)
|
47
|
+
end
|
48
|
+
|
49
|
+
args = args.map{ |s| File.expand_path(s) }
|
50
|
+
files = args.join(' ')
|
51
|
+
|
52
|
+
flags = ""
|
53
|
+
flags += "-r" if (opts[:recurse] || opts[:recursively])
|
54
|
+
flags += " -f" if opts[:force]
|
55
|
+
|
56
|
+
if File.writable? dest_dir then
|
57
|
+
dest = args.size > 1 ? dest_dir : dest
|
58
|
+
logger.info "[file] copying #{files} -> #{dest}"
|
59
|
+
logged_systemu("cp #{flags} #{files} #{dest}")
|
60
|
+
|
61
|
+
else
|
62
|
+
# as root
|
63
|
+
dest = args.size > 1 ? dest_dir : dest
|
64
|
+
logger.info "[file] copying #{files} -> #{dest}"
|
65
|
+
logged_sudo("cp #{flags} #{files} #{dest}")
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
return if !(opts[:chmod] or opts[:chown])
|
70
|
+
|
71
|
+
# need to take care to translate src args to dest path
|
72
|
+
# can't simply pass args into chmod/chown for this reason,
|
73
|
+
# since we want to affect the newly copied files
|
74
|
+
|
75
|
+
if args.length > 1 || args.first.include?("*") then
|
76
|
+
# work on all source files
|
77
|
+
args.each do |s|
|
78
|
+
if s.include? "*" then
|
79
|
+
Dir.glob(s).each{ |e|
|
80
|
+
f = File.join(dest_dir, File.basename(e))
|
81
|
+
chmod(f, opts[:chmod]) if opts[:chmod]
|
82
|
+
chown(f, opts[:chown]) if opts[:chown]
|
83
|
+
}
|
84
|
+
else
|
85
|
+
f = File.join(dest_dir, File.basename(e))
|
86
|
+
chmod(f, opts[:chmod]) if opts[:chmod]
|
87
|
+
chown(f, opts[:chown]) if opts[:chown]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
else
|
92
|
+
# work on a single file
|
93
|
+
if File.directory? dest then
|
94
|
+
dest = File.join(dest, File.basename(args.first))
|
95
|
+
end
|
96
|
+
|
97
|
+
chmod(dest, opts[:chmod]) if opts[:chmod]
|
98
|
+
chown(dest, opts[:chown]) if opts[:chown]
|
99
|
+
end
|
100
|
+
|
101
|
+
end # copy
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
register_dsl FileDSL, "file"
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|