builderator 0.3.15 → 1.0.0.pre.rc.1

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