builderator 0.3.15 → 1.0.0.pre.rc.1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +440 -0
  4. data/README.md +72 -18
  5. data/Rakefile +1 -2
  6. data/VERSION +1 -1
  7. data/bin/build-clean +102 -0
  8. data/bin/build-data +45 -0
  9. data/builderator.gemspec +7 -4
  10. data/docs/configuration.md +154 -0
  11. data/docs/configuration/cookbook.md +19 -0
  12. data/docs/configuration/profile.md +71 -0
  13. data/docs/versioning.md +65 -0
  14. data/lib/builderator.rb +3 -0
  15. data/lib/builderator/config.rb +93 -0
  16. data/lib/builderator/config/attributes.rb +287 -0
  17. data/lib/builderator/config/defaults.rb +163 -0
  18. data/lib/builderator/config/file.rb +336 -0
  19. data/lib/builderator/config/rash.rb +80 -0
  20. data/lib/builderator/control/cleaner.rb +138 -0
  21. data/lib/builderator/control/cookbook.rb +16 -0
  22. data/lib/builderator/control/data.rb +16 -0
  23. data/lib/builderator/control/data/image.rb +98 -0
  24. data/lib/builderator/control/version.rb +128 -0
  25. data/lib/builderator/control/version/auto.rb +48 -0
  26. data/lib/builderator/control/version/bump.rb +82 -0
  27. data/lib/builderator/control/version/comparable.rb +77 -0
  28. data/lib/builderator/control/version/git.rb +45 -0
  29. data/lib/builderator/control/version/scm.rb +92 -0
  30. data/lib/builderator/interface.rb +67 -0
  31. data/lib/builderator/interface/berkshelf.rb +38 -0
  32. data/lib/builderator/interface/packer.rb +75 -0
  33. data/lib/builderator/interface/vagrant.rb +31 -0
  34. data/lib/builderator/metadata.rb +5 -3
  35. data/lib/builderator/model/cleaner.rb +49 -0
  36. data/lib/builderator/model/cleaner/images.rb +93 -0
  37. data/lib/builderator/model/cleaner/instances.rb +58 -0
  38. data/lib/builderator/model/cleaner/launch_configs.rb +47 -0
  39. data/lib/builderator/model/cleaner/scaling_groups.rb +45 -0
  40. data/lib/builderator/model/cleaner/snapshots.rb +50 -0
  41. data/lib/builderator/model/cleaner/volumes.rb +48 -0
  42. data/lib/builderator/patch/berkshelf.rb +18 -0
  43. data/lib/builderator/patch/thor-actions.rb +47 -0
  44. data/lib/builderator/tasks.rb +127 -17
  45. data/lib/builderator/tasks/berkshelf.rb +63 -0
  46. data/lib/builderator/tasks/packer.rb +17 -56
  47. data/lib/builderator/tasks/vagrant.rb +111 -42
  48. data/lib/builderator/tasks/vendor.rb +94 -0
  49. data/lib/builderator/tasks/version.rb +58 -0
  50. data/lib/builderator/util.rb +37 -11
  51. data/lib/builderator/util/aws_exception.rb +1 -1
  52. data/lib/builderator/util/limit_exception.rb +12 -11
  53. data/lib/builderator/util/task_exception.rb +0 -2
  54. data/mkmf.log +4 -0
  55. data/spec/config_spec.rb +30 -0
  56. data/spec/data/Berksfile +6 -0
  57. data/spec/data/Buildfile +0 -0
  58. data/spec/data/Vagrantfile +0 -0
  59. data/spec/data/history.json +483 -0
  60. data/spec/data/packer.json +0 -0
  61. data/spec/interface_spec.rb +36 -0
  62. data/spec/resource/Buildfile +27 -0
  63. data/spec/spec_helper.rb +90 -0
  64. data/spec/version_spec.rb +282 -0
  65. data/template/Berksfile.erb +10 -0
  66. data/template/Buildfile.erb +28 -0
  67. data/template/Gemfile.erb +16 -0
  68. data/template/README.md.erb +61 -0
  69. data/template/Vagrantfile.erb +75 -0
  70. data/template/gitignore.erb +104 -0
  71. data/{.rubocop.yml → template/rubocop.erb} +0 -0
  72. metadata +203 -56
  73. data/.gitignore +0 -14
  74. data/lib/builderator/control/ami.rb +0 -65
  75. data/lib/builderator/control/clean.rb +0 -130
  76. data/lib/builderator/model.rb +0 -46
  77. data/lib/builderator/model/images.rb +0 -89
  78. data/lib/builderator/model/instances.rb +0 -55
  79. data/lib/builderator/model/launch_configs.rb +0 -46
  80. data/lib/builderator/model/scaling_groups.rb +0 -43
  81. data/lib/builderator/model/snapshots.rb +0 -49
  82. data/lib/builderator/model/volumes.rb +0 -48
  83. data/lib/builderator/tasks/ami.rb +0 -47
  84. data/lib/builderator/tasks/berks.rb +0 -68
  85. data/lib/builderator/tasks/clean.rb +0 -97
  86. data/lib/builderator/util/berkshim.rb +0 -34
  87. data/lib/builderator/util/cookbook.rb +0 -87
  88. data/lib/builderator/util/packer.rb +0 -39
  89. data/lib/builderator/util/shell.rb +0 -44
@@ -0,0 +1,48 @@
1
+ require 'aws-sdk'
2
+ require_relative '../../util'
3
+
4
+ module Builderator
5
+ module Model
6
+ # :nodoc:
7
+ module Cleaner
8
+ def self.volumes
9
+ @volumes ||= Volumes.new
10
+ end
11
+
12
+ ##
13
+ # EC2 Volume Resources
14
+ ##
15
+ class Volumes < Model::Cleaner::Base
16
+ PROPERTIES = %w(size availability_zone state volume_type iops)
17
+
18
+ def fetch
19
+ @resources = {}.tap do |v|
20
+ Util.ec2.describe_volumes.each do |page|
21
+ page.volumes.each do |vol|
22
+ properties = Util.from_tags(vol.tags)
23
+ properties['creation_date'] = vol.create_time.to_datetime
24
+ PROPERTIES.each { |pp| properties[pp] = vol[pp.to_sym] }
25
+
26
+ v[vol.volume_id] = {
27
+ :id => vol.volume_id,
28
+ :properties => properties,
29
+ :snapshot => vol.snapshot_id
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def snapshots
37
+ resources.values.map { |v| v[:snapshot] }
38
+ end
39
+
40
+ def in_use
41
+ {}.tap do |used|
42
+ used.merge!(select(Cleaner.instances.volumes))
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ require 'faraday_middleware'
2
+
3
+ module FaradayMiddleware
4
+ # Monkey patch to handle the case where Content-Type headers returned by servers
5
+ # say "gzip" by the resulting message body isn't in gzip format.
6
+ # TODO Remove this when we upgrade Berkshelf and the gzip response goes away.
7
+ # https://github.com/berkshelf/berkshelf-api-client/blob/v1.3.0/lib/berkshelf/api_client/connection.rb#L37
8
+ class Gzip
9
+ alias_method :__uncompress_gzip__, :uncompress_gzip
10
+ def uncompress_gzip(body)
11
+ __uncompress_gzip__(body)
12
+ rescue Zlib::GzipFile::Error
13
+ StringIO.new(body).read
14
+ end
15
+ end
16
+ end
17
+
18
+ Faraday::Response.register_middleware :gzip => FaradayMiddleware::Gzip
@@ -0,0 +1,47 @@
1
+ require 'thor/actions'
2
+
3
+ require_relative '../util'
4
+
5
+ class Thor
6
+ ##
7
+ # Patch some Thor actions
8
+ ##
9
+ module Actions
10
+ ##
11
+ # Replace `run` with IO::popen to accept STDIN
12
+ ##
13
+ def run_with_input(command, input, config = {})
14
+ return unless behavior == :invoke
15
+
16
+ destination = relative_to_original_destination_root(destination_root, false)
17
+ desc = "#{command} from #{destination.inspect}"
18
+
19
+ if config[:with]
20
+ desc = "#{File.basename(config[:with].to_s)} #{desc}"
21
+ command = "#{config[:with]} #{command}"
22
+ end
23
+
24
+ say_status :run, desc, config.fetch(:verbose, true)
25
+ return if options[:pretend]
26
+
27
+ output = config.fetch(:stdout, STDOUT)
28
+
29
+ IO.popen(command, 'r+') do |io|
30
+ io.write(input)
31
+
32
+ ## Stream output
33
+ output.write(io.readpartial(4096)) until io.eof?
34
+ end
35
+ end
36
+
37
+ ##
38
+ # Make `template` load from a sane path and render in the context of Config
39
+ ##
40
+ def template(source, destination, config = {})
41
+ content = ERB.new(Builderator::Util.source_path(source).binread,
42
+ nil, '-', '@output_buffer').result(Builderator::Config.instance_eval('binding'))
43
+
44
+ create_file Builderator::Util.relative_path(destination), content, config
45
+ end
46
+ end
47
+ end
@@ -1,36 +1,146 @@
1
1
  require 'thor'
2
- require_relative './tasks/ami'
3
- require_relative './tasks/berks'
4
- require_relative './tasks/clean'
5
- require_relative './tasks/cookbook'
2
+
3
+ require_relative './config'
4
+ require_relative './patch/thor-actions'
5
+
6
+ # require_relative './tasks/cookbook'
7
+ require_relative './tasks/vendor'
8
+ require_relative './tasks/version'
9
+
10
+ require_relative './tasks/berkshelf'
6
11
  require_relative './tasks/packer'
7
12
  require_relative './tasks/vagrant'
8
13
 
9
14
  module Builderator
10
15
  module Tasks
16
+ ##
17
+ # Top-level command line tasks
18
+ ##
11
19
  class CLI < Thor
12
- desc 'ami SUBCOMMAND', 'Search for AMI IDs'
13
- subcommand 'ami', Builderator::Tasks::AMI
20
+ include Thor::Actions
14
21
 
15
- desc 'berks SUBCOMMAND', 'Berkshelf helpers'
16
- subcommand 'berks', Builderator::Tasks::Berks
22
+ def initialize(*_)
23
+ super
17
24
 
18
- desc 'clean SUBCOMMAND', 'Clean up things'
19
- subcommand 'clean', Builderator::Tasks::Clean
25
+ Config.argv(options) ## Load command flags
26
+ Config.load(File.join(ENV['HOME'], '.builderator/Buildfile'))
27
+ Config.load(Util.relative_path('Buildfile').to_s)
28
+
29
+ Config.compile
30
+ end
31
+
32
+ def self.exit_on_failure?
33
+ true
34
+ end
20
35
 
21
- desc 'cookbook SUBCOMMAND', 'Cookbook tasks'
22
- subcommand 'cookbook', Builderator::Tasks::Cookbook
36
+ ## Globally enable/disable workspace cleanup
37
+ class_option 'cleanup', :type => :boolean, :default => true
23
38
 
39
+ ##
40
+ # Tasks common to local, ec2, and ami builds
41
+ ##
42
+ desc 'prepare', 'Common preparation tasks for Vagrant and Packer'
43
+ def prepare
44
+ invoke Tasks::Version, :current, [], options
45
+ invoke Tasks::Vendor, :all, [], options
46
+ invoke Tasks::Berkshelf, :vendor, [], options
47
+
48
+ # mvn package?
49
+ # invoke Tasks::Cookbook, :prepare, []
50
+ end
51
+
52
+ ##
53
+ # Main commands.
54
+ #
55
+ # `local`, `ec2`, and `build` invoke sets of subcommands to build VMs or images
56
+ ##
57
+ desc 'local [PROFILE = default VAGRANT_ARGS]', 'Provision a local VM of PROFILE'
58
+ def local(*args)
59
+ prepare
60
+ invoke Tasks::Vagrant, :local, args, options
61
+ end
62
+
63
+ desc 'ec2 [PROFILE = default VAGRANT_ARGS]', 'Provision an EC2 instance of PROFILE'
64
+ def ec2(*args)
65
+ prepare
66
+ invoke Tasks::Vagrant, :ec2, args, options
67
+ end
68
+
69
+ desc 'image [PROFILE = default]', 'Build an AMI of PROFILE'
70
+ method_option :debug, :type => :boolean
71
+ def image(profile = :default)
72
+ prepare
73
+ invoke Tasks::Packer, :build, [profile], options
74
+ end
75
+
76
+ # desc 'cookbook SUBCOMMAND', 'Cookbook tasks'
77
+ # subcommand 'cookbook', Tasks::Cookbook
78
+
79
+ desc 'vendor SUBCOMMAND', 'Vendor loading tasks'
80
+ subcommand 'vendor', Tasks::Vendor
81
+
82
+ desc 'version SUBCOMMAND', 'Version management tasks'
83
+ subcommand 'version', Tasks::Version
84
+
85
+ ##
86
+ # Helper/utility commands
87
+ ##
88
+ desc 'config', 'Print compiled configuration'
89
+ def config
90
+ invoke Tasks::Version, :current, [], options
91
+ puts Config.compiled.to_json
92
+ end
93
+
94
+ desc 'clean', 'Run cleanup tasks'
95
+ def clean
96
+ invoke Tasks::Vagrant, :clean
97
+ invoke Tasks::Berkshelf, :clean
98
+ invoke Tasks::Vendor, :clean
99
+ end
100
+
101
+ ##
102
+ # CLI Wrappers
103
+ ##
104
+ desc 'berks SUBCOMMAND', 'Berkshelf helpers'
105
+ subcommand 'berks', Tasks::Berkshelf
24
106
 
25
107
  desc 'packer SUBCOMMAND', 'Run Packer tasks'
26
- subcommand 'packer', Builderator::Tasks::Packer
108
+ subcommand 'packer', Tasks::Packer
27
109
 
28
110
  desc 'vagrant SUBCOMMAND', 'Run Vagrant tasks'
29
- subcommand 'vagrant', Builderator::Tasks::Vagrant
111
+ subcommand 'vagrant', Tasks::Vagrant
112
+
113
+ ##
114
+ # Generator
115
+ ##
116
+ desc 'generate [PROJECT=default]', 'Run a generator'
117
+ method_option 'build-name', :type => :string
118
+ method_option :ignore, :type => :array
119
+ method_option :sync, :type => :array
120
+ method_option :rm, :type => :array
121
+ def generate(project = :default)
122
+ fail 'Please provide a valid build name with the `--build-name=VALUE` option!' unless Config.has?(:build_name)
123
+ Config.generator.project.use(project)
124
+
125
+ Config.generator.project.current.resource.each do |rname, resource|
126
+ next if (options['ignore'] && options['ignore'].include?(rname.to_s)) ||
127
+ resource.action == :ignore
128
+
129
+ if (options['sync'] && options['sync'].include?(rname.to_s)) ||
130
+ resource.action == :sync
131
+ template resource.template, resource.path.first
132
+ next
133
+ end
134
+
135
+ if (options['rm'] && options['rm'].include?(rname.to_s)) ||
136
+ resource.action == :rm
137
+ resource.path.each { |rm| remove_file rm }
138
+ next
139
+ end
30
140
 
31
- desc 'version', 'Print gem version'
32
- def version
33
- puts Builderator::VERSION
141
+ ## Create
142
+ template resource.template, resource.path.first, :skip => true
143
+ end
34
144
  end
35
145
  end
36
146
  end
@@ -0,0 +1,63 @@
1
+ require 'thor'
2
+
3
+ require_relative '../interface/berkshelf'
4
+ require_relative '../patch/thor-actions'
5
+
6
+ module Builderator
7
+ module Tasks
8
+ ##
9
+ # Wrap Berkshelf commands
10
+ ##
11
+ class Berkshelf < Thor
12
+ include Thor::Actions
13
+
14
+
15
+ def self.exit_on_failure?
16
+ true
17
+ end
18
+
19
+ desc 'configure', 'Write a Berksfile into the project workspace'
20
+ def configure
21
+ Interface.berkshelf.write
22
+ end
23
+
24
+ desc 'vendor', 'Vendor a cookbook release and its dependencies'
25
+ def vendor
26
+ invoke :configure, [], options
27
+ empty_directory Interface.berkshelf.vendor
28
+
29
+ command = "#{Interface.berkshelf.command} vendor #{Interface.berkshelf.vendor} "
30
+ command << "-c #{Interface.berkshelf.berkshelf_config} "
31
+ command << "-b #{Interface.berkshelf.source}"
32
+
33
+ inside Interface.berkshelf.directory do
34
+ remove_file Interface.berkshelf.lockfile
35
+ run command
36
+ end
37
+ end
38
+
39
+ desc 'upload', 'Upload the local cookbook source and its dependencies to the Chef server'
40
+ def upload
41
+ vendor
42
+
43
+ command = "#{Interface.berkshelf.command} upload "
44
+ command << "-c #{Interface.berkshelf.berkshelf_config} "
45
+ command << "-b #{Interface.berkshelf.source}"
46
+
47
+ run command
48
+ end
49
+
50
+ desc 'uncache', 'Delete the Berkshelf cache'
51
+ def uncache
52
+ remove_dir File.join(ENV['HOME'], '.berkshelf/cookbooks')
53
+ end
54
+
55
+ desc 'clean', 'Remove a local vendor directory'
56
+ def clean
57
+ remove_dir Interface.berkshelf.vendor
58
+ remove_file Interface.berkshelf.source
59
+ remove_file Interface.berkshelf.lockfile
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,71 +1,32 @@
1
1
  require 'thor'
2
- require 'thor/actions'
3
- require_relative './berks'
4
- require_relative '../util/packer'
5
- require_relative '../util/shell'
2
+
3
+ require_relative '../interface/packer'
4
+ require_relative '../patch/thor-actions'
6
5
 
7
6
  module Builderator
8
7
  module Tasks
8
+ ##
9
+ # Wrap Packer commands
10
+ ##
9
11
  class Packer < Thor
10
12
  include Thor::Actions
11
- include Util::Shell
12
-
13
- class_option :config, :aliases => :c, :desc => "Path to Berkshelf's config.json"
14
- class_option :berksfile, :aliases => :b, :desc => 'Path to the Berksfile to use'
15
-
16
- desc 'install [VERSION = 0.8.2]', 'Ensure that the desired version of packer is installed'
17
- def install(version = '0.8.2')
18
- Util::Packer.use(version)
19
13
 
20
- if Util::Packer.installed?
21
- say_status :packer, "is already installed at version #{ version }"
22
- return
23
- end
24
-
25
- say_status :packer, "install version #{ version } to #{ Util::Packer.path }"
26
- run "wget #{ Util::Packer.url } -O packer.zip -q"
27
- run "unzip -d #{ Util::Packer.path } -q packer.zip"
28
- run "ln -sf #{ Util::Packer.path } $HOME/packer"
14
+ def self.exit_on_failure?
15
+ true
29
16
  end
30
17
 
31
- desc 'build ARGS', 'Run a build with the installed version of packer'
32
- option 'properties-file', :desc => 'Write build outputs to a properties file'
33
- def build(*args)
34
- invoke Tasks::Berks, 'vendor', [], options
35
-
36
- packer_output = execute("#{ Util::Packer.bin } build #{ args.join(' ') }")
18
+ class_option :debug, :type => :boolean
37
19
 
38
- ## Try to find the ID of the new AMI
39
- ami_id_search = /AMI: (ami-[0-9a-f]{8})/.match(packer_output.string)
40
- if ami_id_search.nil? && options.include?('properties-file')
41
- say_status :failure, 'Unable to find AMI ID from packer build', :red
42
- return
43
- end
44
-
45
- return unless options['properties-file']
46
- say_status :success, "Created AMI #{ ami_id_search[1] }"
47
-
48
- create_file options['properties-file'], '', :force => true
49
- append_file options['properties-file'], "image.useast1=#{ ami_id_search[1] }"
20
+ desc 'configure [PROFILE=default]', 'Generate a packer configuration'
21
+ def configure(profile = :default)
22
+ Config.profile.use(profile)
23
+ puts Interface.packer.render if options['debug']
50
24
  end
51
25
 
52
- desc 'find_ami', 'Find the ID of the new AMI from packer output'
53
- option 'properties-file', :desc => 'Write build outputs to a properties file'
54
- def find_ami
55
- tee = Builderator::Util::Shell::BufferTee.new($stdout)
56
- $stdin.each { |l| tee.write(l) } # Buffer stdin
57
-
58
- ami_id_search = /AMI: (ami-[0-9a-f]{8})/.match(tee.string)
59
- if ami_id_search.nil?
60
- say_status :failure, 'Unable to find AMI ID from packer build', :red
61
- return
62
- end
63
-
64
- say_status :success, "Created AMI #{ ami_id_search[1] }"
65
- return unless options['properties-file']
66
-
67
- create_file options['properties-file'], '', :force => true
68
- append_file options['properties-file'], "image.useast1=#{ ami_id_search[1] }"
26
+ desc 'build [PROFILE=default *ARGS]', 'Run a build with the installed version of packer'
27
+ def build(profile = :default, *args)
28
+ invoke :configure, [profile], options
29
+ run_with_input "#{Interface.packer.command} build - #{ args.join('') }", Interface.packer.render
69
30
  end
70
31
  end
71
32
  end
@@ -1,65 +1,134 @@
1
1
  require 'thor'
2
- require 'thor/actions'
3
- require_relative './berks'
2
+
3
+ require_relative '../interface/vagrant'
4
+ require_relative '../patch/thor-actions'
4
5
 
5
6
  module Builderator
6
7
  module Tasks
8
+ ##
9
+ # Wrap vagrant commands
10
+ ##
7
11
  class Vagrant < Thor
8
12
  include Thor::Actions
9
- class_option :config, :aliases => :c, :desc => "Path to Berkshelf's config.json"
10
- class_option :berksfile, :aliases => :b, :desc => 'Path to the Berksfile to use'
11
-
12
- def initialize(*_)
13
- unless Gem.loaded_specs.key?('vagrant')
14
- say '!!! Vagrant is not available in this bundle !!!!', [:red, :bold]
15
- puts ''
16
- say 'Please add the following to your Gemfile and update your bundle to use the `vagrant` command:'
17
- say ' +------------------------------------------------+', :green
18
- say " | gem 'vagrant', :github => 'mitchellh/vagrant', |", :green
19
- say " | :tag => 'v1.7.4' |", :green
20
- say ' +------------------------------------------------+', :green
21
-
22
- exit 1
13
+
14
+ def self.exit_on_failure?
15
+ true
16
+ end
17
+
18
+ desc 'configure [PROFILE]', 'Write a Vagrantfile into the project workspace'
19
+ def configure(profile = :default)
20
+ Config.profile.use(profile)
21
+ Interface.vagrant.write
22
+ end
23
+
24
+ desc 'local [PROFILE [ARGS ...]]', 'Start VirtualBox VM(s)'
25
+ def local(profile = :default, *args)
26
+ invoke :configure, [profile], options
27
+
28
+ inside Interface.vagrant.directory do
29
+ command = Interface.vagrant.command
30
+ command << " up --provider=#{Config.profile.current.vagrant.local.provider} "
31
+ command << args.join(' ')
32
+
33
+ run command
23
34
  end
35
+ end
36
+
37
+ desc 'ec2 [PROFILE [ARGS ...]]', 'Start EC2 instances'
38
+ def ec2(profile = :default, *args)
39
+ invoke :configure, [profile], options
40
+
41
+ inside Interface.vagrant.directory do
42
+ command = Interface.vagrant.command
43
+ command << " up --provider=#{Config.profile.current.vagrant.ec2.provider} "
44
+ command << args.join(' ')
45
+
46
+ run command
47
+ end
48
+ end
49
+
50
+ desc 'provision [PROFILE [ARGS ...]]', 'Reprovision Vagrant VM(s)'
51
+ def provision(profile = :default, *args)
52
+ invoke :configure, [profile], options
53
+
54
+ inside Interface.vagrant.directory do
55
+ command = Interface.vagrant.command
56
+ command << " provision #{args.join(' ')}"
24
57
 
25
- super
58
+ run command
59
+ end
26
60
  end
27
61
 
28
- desc 'up ARGS', 'Start Vagrant VM(s)'
29
- def up(*args)
30
- command = 'ulimit -n 1024;'
31
- command << ' VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET=true'
32
- command << " vagrant up #{ args.join(' ') }"
62
+ desc 'status [PROFILE [ARGS ...]]', 'Reprovision Vagrant VM(s)'
63
+ def status(profile = :default, *args)
64
+ invoke :configure, [profile], options
65
+
66
+ inside Interface.vagrant.directory do
67
+ command = Interface.vagrant.command
68
+ command << " status #{args.join(' ')}"
33
69
 
34
- invoke Tasks::Berks, 'local', [], options
35
- run command
70
+ run command
71
+ end
36
72
  end
37
73
 
38
- desc 'provision ARGS', 'Provision Vagrant VM(s)'
39
- def provision(*args)
40
- command = 'ulimit -n 1024;'
41
- command << ' VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET=true'
42
- command << " vagrant provision #{ args.join(' ') }"
74
+ desc 'ssh [PROFILE [ARGS ...]]', 'SSH into Vagrant VM(s)'
75
+ def ssh(profile = :default, *args)
76
+ invoke :configure, [profile], options
77
+
78
+ inside Interface.vagrant.directory do
79
+ command = Interface.vagrant.command
80
+ command << " ssh #{args.join(' ')}"
43
81
 
44
- invoke Tasks::Berks, 'local', [], options
45
- run command
82
+ ## Connect to subprocesses STDIO
83
+ exec(command)
84
+ end
46
85
  end
47
86
 
48
- desc 'destroy ARGS', 'Destroy Vagrant VM(s)'
49
- option :force, :aliases => :f, :type => :boolean
50
- def destroy(*args)
51
- command = 'ulimit -n 1024;'
52
- command << ' VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET=true'
53
- command << " vagrant destroy #{ args.join(' ') }"
54
- command << ' -f' if options['force']
87
+ desc 'destroy [PROFILE [ARGS ...]]', 'Destroy Vagrant VM(s)'
88
+ method_option :force, :aliases => :f, :type => :boolean, :default => true
89
+ def destroy(profile = :default, *args)
90
+ invoke :configure, [profile], options
91
+
92
+ inside Interface.vagrant.directory do
93
+ command = Interface.vagrant.command
94
+ command << " destroy #{args.join(' ')}"
95
+ command << ' -f' if options['force']
55
96
 
56
- run command
97
+ run command
98
+ end
57
99
  end
58
100
 
59
101
  desc 'rebuild ARGS', 'Destroy and recreate Vagrant VM(s)'
60
- def rebuild(*args)
61
- invoke Tasks::Vagrant, 'destroy', args, options.merge('force' => true)
62
- invoke Tasks::Vagrant, 'up', args, options
102
+ method_option :force, :aliases => :f, :type => :boolean, :default => true
103
+ def rebuild(profile = :default, *args)
104
+ destroy(profile, *args)
105
+ up(profile, *args)
106
+ end
107
+
108
+ desc 'clean', 'Destroy VMs and clean up local files'
109
+ method_option :force, :aliases => :f, :type => :boolean, :default => true
110
+ def clean(profile = :default)
111
+ destroy(profile)
112
+
113
+ remove_dir Interface.vagrant.directory.join('.vagrant')
114
+ remove_file Interface.vagrant.source
115
+ end
116
+
117
+ desc 'plugins [PROJECT=default]', 'Install plugins required for PROJECT'
118
+ def plugins(project = :default)
119
+ if Interface.vagrant.bundled?
120
+ say 'Vagrant is already bundled. Required plugins are already part of the bundle as well'
121
+ return
122
+ end
123
+
124
+ Config.generator.project.use(project)
125
+ Config.generator.project.current.vagrant.plugin.each do |pname, plugin|
126
+ command = Interface.vagrant.command
127
+ command << " plugin install #{ pname }"
128
+ command << " --plugin-version #{ plugin.version }" if plugin.has?(:version)
129
+
130
+ run command
131
+ end
63
132
  end
64
133
  end
65
134
  end