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,43 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
module Packager
|
5
|
+
class Yum < PackagerBase
|
6
|
+
|
7
|
+
module MongoDB
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def install_mongodb(opts)
|
12
|
+
|
13
|
+
file = File.join(YUM_REPOS_D, "mongodb.repo")
|
14
|
+
if File.exists?(file) then
|
15
|
+
logger.info "[yum] mongodb repo already installed"
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
logger.info "[yum] installing mongodb repo"
|
20
|
+
|
21
|
+
arch = amd64?() ? "x86_64" : "i686"
|
22
|
+
|
23
|
+
File.open(file, 'w') do |f|
|
24
|
+
f.puts <<-EOF
|
25
|
+
[mongodb]
|
26
|
+
name=MongoDB Repository
|
27
|
+
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/#{arch}/
|
28
|
+
gpgcheck=0
|
29
|
+
enabled=1
|
30
|
+
EOF
|
31
|
+
end
|
32
|
+
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
end # MongoDB
|
37
|
+
|
38
|
+
Yum.register_plugin(MongoDB)
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
|
5
|
+
class RunControl < Base
|
6
|
+
|
7
|
+
EXPORTS = [:first_boot]
|
8
|
+
|
9
|
+
def first_boot(&block)
|
10
|
+
if first_boot_has_run? then
|
11
|
+
logger.info "first_boot already ran"
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
logger.info "running first_boot block"
|
16
|
+
begin
|
17
|
+
block.call
|
18
|
+
rescue Exception => ex
|
19
|
+
# TODO fail!
|
20
|
+
raise ex
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
touch_first_boot_state
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def first_boot_has_run?
|
31
|
+
File.exists?(first_boot_state)
|
32
|
+
end
|
33
|
+
|
34
|
+
def first_boot_state
|
35
|
+
Bixby.path("var", "provision", "first_boot")
|
36
|
+
end
|
37
|
+
|
38
|
+
def touch_first_boot_state
|
39
|
+
f = first_boot_state
|
40
|
+
FileUtils.mkdir_p(File.dirname(f))
|
41
|
+
FileUtils.touch(f)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
register_dsl RunControl, "run_control"
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
require "bixby/provision/dsl/scm/base"
|
3
|
+
require "bixby/provision/dsl/scm/git"
|
4
|
+
require "bixby/provision/dsl/scm/svn"
|
5
|
+
|
6
|
+
module Bixby
|
7
|
+
module Provision
|
8
|
+
|
9
|
+
class SCM < Base
|
10
|
+
|
11
|
+
EXPORTS = [:checkout]
|
12
|
+
|
13
|
+
def checkout(uri, opts={})
|
14
|
+
handler(uri).checkout(uri, opts)
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def handler(uri)
|
21
|
+
@handler ||= if uri =~ %r{\.git$} then
|
22
|
+
SCM::Git.new(self)
|
23
|
+
else
|
24
|
+
# TODO add check
|
25
|
+
SCM::SVN.new(self)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
register_dsl SCM
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
|
2
|
+
require "git"
|
3
|
+
|
4
|
+
module Bixby
|
5
|
+
module Provision
|
6
|
+
class SCM < Base
|
7
|
+
|
8
|
+
class Git < SCMBase
|
9
|
+
|
10
|
+
def checkout(uri, opts)
|
11
|
+
path = opts.delete(:path)
|
12
|
+
branch = opts.delete(:branch) || "master"
|
13
|
+
|
14
|
+
if path.nil? then
|
15
|
+
# TODO raise
|
16
|
+
end
|
17
|
+
path = File.expand_path(path)
|
18
|
+
if File.directory? File.join(path, ".git") then
|
19
|
+
logger.info "repository already checked out at #{path}"
|
20
|
+
return
|
21
|
+
end
|
22
|
+
dir.create(path)
|
23
|
+
|
24
|
+
# https://github.com/user/repo.git
|
25
|
+
# git@github.com:user/repo.git
|
26
|
+
# ssh://hg@bitbucket.org/user/repo
|
27
|
+
if uri !~ %r{https?://} && uri =~ %r{^(ssh://)?(.*?@)(.*?)[:/]} then
|
28
|
+
ensure_ssh_verify($3)
|
29
|
+
end
|
30
|
+
|
31
|
+
sys.package "git"
|
32
|
+
|
33
|
+
logger.info "[scm] cloning #{uri} into #{path}, branch: #{branch}"
|
34
|
+
g = ::Git.clone(uri, File.basename(path), :path => File.dirname(path))
|
35
|
+
g.checkout(branch) if branch != "master"
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Ensure that StrictHostKeyChecking is disabled for the given host
|
42
|
+
#
|
43
|
+
# @param [String] host
|
44
|
+
def ensure_ssh_verify(host)
|
45
|
+
|
46
|
+
config = File.expand_path("~/.ssh/config")
|
47
|
+
str = ""
|
48
|
+
str = File.read(config) if File.exists? config
|
49
|
+
|
50
|
+
add = str.empty?
|
51
|
+
if !add then
|
52
|
+
# see if it's already disabled for the given host
|
53
|
+
found_host = false
|
54
|
+
found_strict = false
|
55
|
+
str.split(/n/).each do |l|
|
56
|
+
|
57
|
+
if l =~ /^\s*Host (.*?)/ then
|
58
|
+
if found_host then
|
59
|
+
add = true if !found_strict
|
60
|
+
found_host = false
|
61
|
+
next
|
62
|
+
end
|
63
|
+
if $1 == host then
|
64
|
+
found_host = true
|
65
|
+
end
|
66
|
+
|
67
|
+
elsif found_host && l =~ /StrictHostKeyChecking \s*no/ then
|
68
|
+
found_strict = true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
return if !add
|
74
|
+
|
75
|
+
logger.info "[scm] disabling StrictHostKeyChecking for #{host}"
|
76
|
+
str += "\n"
|
77
|
+
str += "Host #{host}\n"
|
78
|
+
str += " StrictHostKeyChecking no\n"
|
79
|
+
|
80
|
+
dir.mkdir "~/.ssh", :chmod => "700"
|
81
|
+
File.open(config, 'w'){ |f| f.write(str) }
|
82
|
+
chmod config, "644"
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
require "bixby/provision/dsl/services/base"
|
3
|
+
require "bixby/provision/dsl/services/init"
|
4
|
+
|
5
|
+
module Bixby
|
6
|
+
module Provision
|
7
|
+
|
8
|
+
class Service < Base
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
super
|
12
|
+
@services = if ubuntu? then
|
13
|
+
Services::Init.new(self)
|
14
|
+
elsif centos? or amazon? then
|
15
|
+
Services::Init.new(self)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def start(name, opts={})
|
20
|
+
if !running?(name) || opts[:force] == true then
|
21
|
+
@services.start(name, opts)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop(name, opts={})
|
26
|
+
if running?(name) || opts[:force] == true then
|
27
|
+
@services.stop(name, opts)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def restart(name, opts={})
|
32
|
+
@services.restart(name, opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def reload(name, opts={})
|
36
|
+
@services.reload(name, opts)
|
37
|
+
end
|
38
|
+
|
39
|
+
def running?(name)
|
40
|
+
@services.running?(name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def ensure(name)
|
44
|
+
if centos? or amazon? then
|
45
|
+
logged_sudo("chkconfig --add #{name}")
|
46
|
+
elsif ubuntu? then
|
47
|
+
logged_sudo("update-rc.d #{name} defaults")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
register_dsl Service
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
module Services
|
5
|
+
|
6
|
+
class Init < ServiceBase
|
7
|
+
|
8
|
+
def start(name, opts={})
|
9
|
+
init("#{name} start")
|
10
|
+
end
|
11
|
+
|
12
|
+
def stop(name, opts={})
|
13
|
+
init("#{name} stop")
|
14
|
+
end
|
15
|
+
|
16
|
+
def restart(name, opts={})
|
17
|
+
init("#{name} restart")
|
18
|
+
end
|
19
|
+
|
20
|
+
def reload(name, opts={})
|
21
|
+
init("#{name} reload")
|
22
|
+
end
|
23
|
+
|
24
|
+
def running?(name)
|
25
|
+
cmd = init("#{name} status")
|
26
|
+
return cmd.success? # exit 0 means it's running (usually.. hopefully!)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def init(args)
|
33
|
+
logged_sudo("/etc/init.d/#{args}")
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
require "bixby/provision/dsl/packager/base"
|
3
|
+
require "bixby/provision/dsl/packager/apt"
|
4
|
+
require "bixby/provision/dsl/packager/yum"
|
5
|
+
require "bixby/provision/dsl/packager/npm"
|
6
|
+
|
7
|
+
module Bixby
|
8
|
+
module Provision
|
9
|
+
|
10
|
+
class System < Base
|
11
|
+
|
12
|
+
EXPORTS = [:refresh_packages, :upgrade_system, :package, :repo]
|
13
|
+
|
14
|
+
attr_reader :packager
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
super
|
18
|
+
@packager = if ubuntu? then
|
19
|
+
Packager::Apt.new(self)
|
20
|
+
elsif centos? or amazon? then
|
21
|
+
Packager::Yum.new(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def refresh_packages
|
26
|
+
logger.info "[sys] refresh_packages"
|
27
|
+
packager.refresh
|
28
|
+
end
|
29
|
+
|
30
|
+
def upgrade_system
|
31
|
+
logger.info "[sys] upgrade_system"
|
32
|
+
packager.upgrade_system
|
33
|
+
end
|
34
|
+
|
35
|
+
def package(*packages)
|
36
|
+
packages.flatten!
|
37
|
+
logger.info "[sys] installing packages: " + packages.join(" ")
|
38
|
+
packager.install(*packages)
|
39
|
+
end
|
40
|
+
alias_method :packages, :package
|
41
|
+
|
42
|
+
def repo(name, opts={})
|
43
|
+
if packager.install_repo(name, opts) then
|
44
|
+
refresh_packages
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
register_dsl System, "sys"
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
|
2
|
+
module Bixby
|
3
|
+
module Provision
|
4
|
+
module Util
|
5
|
+
module File
|
6
|
+
|
7
|
+
def chown(path, chown, opts={})
|
8
|
+
if chown.nil? then
|
9
|
+
return
|
10
|
+
end
|
11
|
+
chown.strip!
|
12
|
+
return if chown.empty?
|
13
|
+
|
14
|
+
user, group = chown.split(/:/)
|
15
|
+
user = Process.uid if user == "$USER"
|
16
|
+
group = Process.gid if group == "$GROUP"
|
17
|
+
uid = get_uid(user)
|
18
|
+
gid = get_gid(group)
|
19
|
+
|
20
|
+
logger.info "[chown] #{path} -> '#{get_user(uid)}" + (gid ? ":#{get_group(gid)}'" : "'")
|
21
|
+
|
22
|
+
# always as root
|
23
|
+
if opts[:recurse] or opts[:recursively] then
|
24
|
+
logged_sudo("chown -R #{uid}:#{gid} #{path}")
|
25
|
+
else
|
26
|
+
logged_sudo("chown #{uid}:#{gid} #{path}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Change mode of the given path
|
31
|
+
#
|
32
|
+
# @param [String] path
|
33
|
+
# @param [String] mode File mode given as a string, same as the input to the `chmod` command
|
34
|
+
def chmod(path, mode, opts={})
|
35
|
+
return if mode.nil?
|
36
|
+
|
37
|
+
if mode.kind_of? String then
|
38
|
+
mode.strip!
|
39
|
+
return if mode.empty?
|
40
|
+
|
41
|
+
elsif mode.kind_of? Fixnum then
|
42
|
+
# mode should always be a string
|
43
|
+
# convert fixnum to octal
|
44
|
+
mode = sprintf("%o", mode)
|
45
|
+
if mode.length > 4 then
|
46
|
+
# only want the right-most 4 chars
|
47
|
+
# ex: File.stat = mode=0100440 (file r--r-----) => 33056 => "100440" => "0440"
|
48
|
+
mode = mode[mode.length-4, mode.length]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
logger.info "[chmod] #{path} -> '#{mode}'"
|
53
|
+
|
54
|
+
# always as root
|
55
|
+
if opts[:recurse] or opts[:recursively] then
|
56
|
+
logged_sudo("chmod -R #{mode} #{path}")
|
57
|
+
else
|
58
|
+
logged_sudo("chmod #{mode} #{path}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get the SHA-256 hex digest of the given file
|
63
|
+
#
|
64
|
+
# @param [String] filename
|
65
|
+
#
|
66
|
+
# @return [String] sha256 hash in hexadecimal form
|
67
|
+
def sha256sum(filename)
|
68
|
+
if ::File.readable? filename then
|
69
|
+
return Digest::SHA2.new(256).file(filename).hexdigest()
|
70
|
+
end
|
71
|
+
|
72
|
+
# read as root
|
73
|
+
if cmd = which("sha256sum") then
|
74
|
+
return logged_sudo("#{cmd} #{filename}").stdout.split(/\s+/).first
|
75
|
+
end
|
76
|
+
|
77
|
+
# use cat - may not work for binaries
|
78
|
+
str = logged_sudo("cat #{filename}").stdout
|
79
|
+
return Digest::SHA2.new(256).update(str).hexdigest()
|
80
|
+
end
|
81
|
+
|
82
|
+
# Locate the given command, if it exists
|
83
|
+
#
|
84
|
+
# @param [String] cmd to locate
|
85
|
+
#
|
86
|
+
# @return [String] path to command if it exists, or nil
|
87
|
+
def which(cmd)
|
88
|
+
ret = systemu("which #{cmd}")
|
89
|
+
if ret.success? then
|
90
|
+
return ret.stdout.strip
|
91
|
+
else
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
alias_method :command_exists?, :which
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|