bixby-provision 0.1.0

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