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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +29 -0
  3. data/Gemfile.lock +192 -0
  4. data/Rakefile +13 -0
  5. data/VERSION +1 -0
  6. data/Vagrantfile +64 -0
  7. data/bin/bixby-provision +6 -0
  8. data/bixby-provision.gemspec +113 -0
  9. data/lib/bixby-provision.rb +2 -0
  10. data/lib/bixby/provision.rb +65 -0
  11. data/lib/bixby/provision/app.rb +34 -0
  12. data/lib/bixby/provision/dsl.rb +23 -0
  13. data/lib/bixby/provision/dsl/base.rb +76 -0
  14. data/lib/bixby/provision/dsl/bundler.rb +18 -0
  15. data/lib/bixby/provision/dsl/config.rb +124 -0
  16. data/lib/bixby/provision/dsl/dir.rb +34 -0
  17. data/lib/bixby/provision/dsl/file.rb +108 -0
  18. data/lib/bixby/provision/dsl/inventory.rb +18 -0
  19. data/lib/bixby/provision/dsl/meteor.rb +30 -0
  20. data/lib/bixby/provision/dsl/nodejs.rb +73 -0
  21. data/lib/bixby/provision/dsl/npm.rb +18 -0
  22. data/lib/bixby/provision/dsl/ntp.rb +41 -0
  23. data/lib/bixby/provision/dsl/packager/apt.rb +46 -0
  24. data/lib/bixby/provision/dsl/packager/base.rb +11 -0
  25. data/lib/bixby/provision/dsl/packager/npm.rb +67 -0
  26. data/lib/bixby/provision/dsl/packager/yum.rb +100 -0
  27. data/lib/bixby/provision/dsl/packager/yum/epel.rb +71 -0
  28. data/lib/bixby/provision/dsl/packager/yum/mongodb.rb +43 -0
  29. data/lib/bixby/provision/dsl/ruby.rb +21 -0
  30. data/lib/bixby/provision/dsl/run_control.rb +49 -0
  31. data/lib/bixby/provision/dsl/scm.rb +34 -0
  32. data/lib/bixby/provision/dsl/scm/base.rb +11 -0
  33. data/lib/bixby/provision/dsl/scm/git.rb +89 -0
  34. data/lib/bixby/provision/dsl/scm/svn.rb +11 -0
  35. data/lib/bixby/provision/dsl/service.rb +56 -0
  36. data/lib/bixby/provision/dsl/services/base.rb +11 -0
  37. data/lib/bixby/provision/dsl/services/init.rb +40 -0
  38. data/lib/bixby/provision/dsl/system.rb +53 -0
  39. data/lib/bixby/provision/dsl/util/file.rb +100 -0
  40. data/lib/bixby/provision/dsl/variable.rb +27 -0
  41. data/lib/bixby/provision/manifest.rb +49 -0
  42. data/lib/bixby/provision/manifest/dsl_proxy.rb +17 -0
  43. data/manifest.rb +31 -0
  44. data/tasks/coverage.rake +2 -0
  45. data/tasks/jeweler.rake +21 -0
  46. data/tasks/test.rake +5 -0
  47. data/tasks/yard.rake +2 -0
  48. 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,21 @@
1
+
2
+ module Bixby
3
+ module Provision
4
+
5
+ class Ruby < Base
6
+
7
+ EXPORTS = [:gem]
8
+
9
+ def install(opts={})
10
+ logger.info "ruby.install"
11
+ end
12
+
13
+ def gem(name, opts={})
14
+ end
15
+
16
+ end
17
+
18
+ register_dsl Ruby
19
+
20
+ end
21
+ 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,11 @@
1
+
2
+ module Bixby
3
+ module Provision
4
+ class SCM < Base
5
+
6
+ class SCMBase < Base
7
+ end
8
+
9
+ end
10
+ end
11
+ 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,11 @@
1
+
2
+ module Bixby
3
+ module Provision
4
+ class SCM < Base
5
+
6
+ class SVN < SCMBase
7
+ end
8
+
9
+ end
10
+ end
11
+ 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,11 @@
1
+
2
+ module Bixby
3
+ module Provision
4
+ module Services
5
+
6
+ class ServiceBase < Base
7
+ end
8
+
9
+ end
10
+ end
11
+ 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