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,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,18 @@
1
+
2
+ module Bixby
3
+ module Provision
4
+
5
+ class Bundler < Base
6
+
7
+ EXPORTS = []
8
+
9
+ def install(opts={})
10
+ logger.info "bundle.install"
11
+ end
12
+
13
+ end
14
+
15
+ register_dsl Bundler, "bundle"
16
+
17
+ end
18
+ 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
@@ -0,0 +1,18 @@
1
+
2
+ module Bixby
3
+ module Provision
4
+
5
+ class Inventory < Base
6
+
7
+ EXPORTS = []
8
+
9
+ def tags(*args)
10
+ puts "would register tags: #{args}"
11
+ end
12
+
13
+ end
14
+
15
+ register_dsl Inventory
16
+
17
+ end
18
+ end