vagrant-fifo 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+ require "log4r"
2
+
3
+ require "vagrant/util/subprocess"
4
+
5
+ module VagrantPlugins
6
+ module Fifo
7
+ module Action
8
+ # This middleware uses `rsync` to sync the folders over to the
9
+ # Fifo instance.
10
+ class SyncFolders
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("vagrant_fifo::action::sync_folders")
14
+ end
15
+
16
+ def call(env)
17
+ @app.call(env)
18
+
19
+ ssh_info = env[:machine].ssh_info
20
+
21
+ env[:machine].config.vm.synced_folders.each do |id, data|
22
+ hostpath = File.expand_path(data[:hostpath], env[:root_path])
23
+ guestpath = data[:guestpath]
24
+
25
+ # Make sure there is a trailing slash on the host path to
26
+ # avoid creating an additional directory with rsync
27
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
28
+
29
+ env[:ui].info(I18n.t("vagrant_fifo.rsync_folder",
30
+ :hostpath => hostpath,
31
+ :guestpath => guestpath))
32
+
33
+ # Create the guest path
34
+ env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
35
+ env[:machine].communicate.sudo(
36
+ "chown #{ssh_info[:username]} '#{guestpath}'")
37
+
38
+ # Rsync over to the guest path using the SSH info
39
+ command = [
40
+ "rsync", "--verbose", "--archive", "-z",
41
+ "-e", "ssh -o StrictHostKeyChecking=no -p #{ssh_info[:port]} -i '#{ssh_info[:private_key_path]}'",
42
+ hostpath,
43
+ "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}" ]
44
+
45
+ r = Vagrant::Util::Subprocess.execute(*command)
46
+ if r.exit_code != 0
47
+ raise Errors::RsyncError,
48
+ :guestpath => guestpath,
49
+ :hostpath => hostpath,
50
+ :stderr => r.stderr
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module Fifo
5
+ module Action
6
+ # This terminates the running instance.
7
+ class TerminateInstance
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_fifo::action::run_instance")
11
+ end
12
+
13
+ def call(env)
14
+ server = env[:fifo_compute].vms.get(env[:machine].id)
15
+
16
+ # Destroy the server and remove the tracking ID
17
+ env[:ui].info(I18n.t("vagrant_fifo.terminating"))
18
+
19
+ # Machine must be in a stopped state before it's destroyed.
20
+ #
21
+ # More info here:
22
+ #
23
+ # https://us-west-1.api.fifocloud.com/docs#DeleteMachine
24
+ #
25
+ env[:fifo_compute].vms.delete(server['uuid'])
26
+
27
+ # Wait for server to be completely gone from invetory
28
+ while true do
29
+ ids = env[:fifo_compute].vms.list
30
+
31
+ unless ids.include?(env[:machine].id) then
32
+ break
33
+ end
34
+ sleep 5
35
+ end
36
+
37
+ env[:machine].id = nil
38
+
39
+ @app.call(env)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ require "vagrant-fifo/util/timer"
2
+
3
+ module VagrantPlugins
4
+ module Fifo
5
+ module Action
6
+ # This is the same as the builtin provision except it times the
7
+ # provisioner runs.
8
+ class TimedProvision < Vagrant::Action::Builtin::Provision
9
+ def run_provisioner(env, name, p)
10
+ timer = Util::Timer.time do
11
+ super
12
+ end
13
+
14
+ env[:metrics] ||= {}
15
+ env[:metrics]["provisioner_times"] ||= []
16
+ env[:metrics]["provisioner_times"] << [name, timer]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module Fifo
3
+ module Action
4
+ class WarnNetworks
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].config.vm.networks.length > 0
11
+ env[:ui].warn(I18n.t("vagrant_fifo.warn_networks"))
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,112 @@
1
+ require "pathname"
2
+
3
+ require "vagrant/action/builder"
4
+
5
+ module VagrantPlugins
6
+ module Fifo
7
+ module Action
8
+ # Include the built-in modules so we can use them as top-level things.
9
+ include Vagrant::Action::Builtin
10
+
11
+ # This action is called to terminate the remote machine.
12
+ def self.action_destroy
13
+ Vagrant::Action::Builder.new.tap do |b|
14
+ b.use Call, DestroyConfirm do |env, b2|
15
+ if env[:result]
16
+ b2.use ConfigValidate
17
+ b2.use ConnectFifo
18
+ b2.use TerminateInstance
19
+ else
20
+ b2.use MessageWillNotDestroy
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ # This action is called when `vagrant provision` is called.
27
+ def self.action_provision
28
+ Vagrant::Action::Builder.new.tap do |b|
29
+ b.use ConfigValidate
30
+ b.use Call, IsCreated do |env, b2|
31
+ if !env[:result]
32
+ b2.use MessageNotCreated
33
+ next
34
+ end
35
+
36
+ b2.use Provision
37
+ b2.use SyncFolders
38
+ end
39
+ end
40
+ end
41
+
42
+ # This action is called to read the SSH info of the machine. The
43
+ # resulting state is expected to be put into the `:machine_ssh_info`
44
+ # key.
45
+ def self.action_read_ssh_info
46
+ Vagrant::Action::Builder.new.tap do |b|
47
+ b.use ConfigValidate
48
+ b.use ConnectFifo
49
+ b.use ReadSSHInfo
50
+ end
51
+ end
52
+
53
+ # This action is called to read the state of the machine. The
54
+ # resulting state is expected to be put into the `:machine_state_id`
55
+ # key.
56
+ def self.action_read_state
57
+ Vagrant::Action::Builder.new.tap do |b|
58
+ b.use ConfigValidate
59
+ b.use ConnectFifo
60
+ b.use ReadState
61
+ end
62
+ end
63
+
64
+ # This action is called to SSH into the machine.
65
+ def self.action_ssh
66
+ Vagrant::Action::Builder.new.tap do |b|
67
+ b.use ConfigValidate
68
+ b.use Call, IsCreated do |env, b2|
69
+ if !env[:result]
70
+ b2.use MessageNotCreated
71
+ next
72
+ end
73
+
74
+ b2.use SSHExec
75
+ end
76
+ end
77
+ end
78
+
79
+ # This action is called to bring the box up from nothing.
80
+ def self.action_up
81
+ Vagrant::Action::Builder.new.tap do |b|
82
+ b.use ConfigValidate
83
+ b.use ConnectFifo
84
+ b.use Call, IsCreated do |env, b2|
85
+ if env[:result]
86
+ b2.use MessageAlreadyCreated
87
+ next
88
+ end
89
+
90
+ b2.use TimedProvision
91
+ b2.use SyncFolders
92
+ b2.use RunInstance
93
+ end
94
+ end
95
+ end
96
+
97
+ # The autoload farm
98
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
99
+ autoload :ConnectFifo, action_root.join("connect_fifo")
100
+ autoload :IsCreated, action_root.join("is_created")
101
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
102
+ autoload :MessageNotCreated, action_root.join("message_not_created")
103
+ autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
104
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
105
+ autoload :ReadState, action_root.join("read_state")
106
+ autoload :RunInstance, action_root.join("run_instance")
107
+ autoload :SyncFolders, action_root.join("sync_folders")
108
+ autoload :TimedProvision, action_root.join("timed_provision")
109
+ autoload :TerminateInstance, action_root.join("terminate_instance")
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,64 @@
1
+ #: utf-8 -*-
2
+ require "vagrant"
3
+
4
+ module VagrantPlugins
5
+ module Fifo
6
+ class Config < Vagrant.plugin("2", :config)
7
+ attr_accessor :username
8
+ attr_accessor :password
9
+ attr_accessor :api_url
10
+ attr_accessor :dataset
11
+ attr_accessor :package
12
+ attr_accessor :iprange
13
+ attr_accessor :node_name
14
+ attr_accessor :ssh_username
15
+ attr_accessor :ssh_private_key_path
16
+
17
+ def initialize(datacenter_specific=false)
18
+ @username = UNSET_VALUE
19
+ @password = UNSET_VALUE
20
+ @api_url = UNSET_VALUE
21
+ @dataset = UNSET_VALUE
22
+ @package = UNSET_VALUE
23
+ @iprange = UNSET_VALUE
24
+ @node_name = UNSET_VALUE
25
+ @ssh_username = UNSET_VALUE
26
+ @ssh_private_key_path = UNSET_VALUE
27
+ end
28
+
29
+ #-------------------------------------------------------------------
30
+ # Internal methods.
31
+ #-------------------------------------------------------------------
32
+
33
+ def finalize!
34
+ # API
35
+ @username = nil if @username == UNSET_VALUE
36
+ @password = nil if @password == UNSET_VALUE
37
+ @api_url = nil if @api_url == UNSET_VALUE
38
+
39
+ # Machines
40
+ @dataset = nil if @dataset == UNSET_VALUE
41
+ @package = "medium" if @package == UNSET_VALUE
42
+ @iprange = "default" if @iprange == UNSET_VALUE
43
+ @node_name = nil if @node_name == UNSET_VALUE
44
+ @ssh_username = "root" if @ssh_username == UNSET_VALUE
45
+ @ssh_private_key_path = nil if @ssh_private_key_path == UNSET_VALUE
46
+ end
47
+
48
+ def validate(machine)
49
+ config = self.class.new(true)
50
+
51
+ errors = []
52
+ errors << I18n.t("vagrant_fifo.config.username_required") if config.username.nil?
53
+ errors << I18n.t("vagrant_fifo.config.password_required") if config.password.nil?
54
+ errors << I18n.t("vagrant_fifo.config.api_url_required") if config.api_url.nil?
55
+ errors << I18n.t("vagrant_fifo.config.dataset_required") if config.dataset.nil?
56
+ errors << I18n.t("vagrant_fifo.config.package_required") if config.package.nil?
57
+ errors << I18n.t("vagrant_fifo.config.iprange_required") if config.iprange.nil?
58
+ errors << I18n.t("vagrant_fifo.config.ssh_username_required") if config.ssh_username.nil?
59
+ errors << I18n.t("vagrant_fifo.config.ssh_private_key_path_required") if config.ssh_private_key_path.nil?
60
+ { "Fifo Provider" => errors }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,19 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Fifo
5
+ module Errors
6
+ class VagrantFifoError < Vagrant::Errors::VagrantError
7
+ error_namespace("vagrant_fifo.errors")
8
+ end
9
+
10
+ class FogError < VagrantFifoError
11
+ error_key(:fog_error)
12
+ end
13
+
14
+ class RsyncError < VagrantFifoError
15
+ error_key(:rsync_error)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,73 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant Fifo plugin must be run within Vagrant."
5
+ end
6
+
7
+ # This is a sanity check to make sure no one is attempting to install
8
+ # this into an early Vagrant version.
9
+ if Vagrant::VERSION < "1.1.0"
10
+ raise "The Vagrant Fifo plugin is only compatible with Vagrant 1.1+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module Fifo
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "Fifo"
17
+ description <<-DESC
18
+ This plugin installs a provider that allows Vagrant to manage
19
+ machines in Project-Fifo.
20
+ DESC
21
+
22
+ config(:fifo, :provider) do
23
+ require_relative "config"
24
+ Config
25
+ end
26
+
27
+ provider(:fifo) do
28
+ # Setup logging and i18n
29
+ setup_logging
30
+ setup_i18n
31
+
32
+ # Return the provider
33
+ require_relative "provider"
34
+ Provider
35
+ end
36
+
37
+ # This initializes the internationalization strings.
38
+ def self.setup_i18n
39
+ I18n.load_path << File.expand_path("locales/en.yml", Fifo.source_root)
40
+ I18n.reload!
41
+ end
42
+
43
+ # This sets up our log level to be whatever VAGRANT_LOG is.
44
+ def self.setup_logging
45
+ require "log4r"
46
+
47
+ level = nil
48
+ begin
49
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
50
+ rescue NameError
51
+ # This means that the logging constant wasn't found,
52
+ # which is fine. We just keep `level` as `nil`. But
53
+ # we tell the user.
54
+ level = nil
55
+ end
56
+
57
+ # Some constants, such as "true" resolve to booleans, so the
58
+ # above error checking doesn't catch it. This will check to make
59
+ # sure that the log level is an integer, as Log4r requires.
60
+ level = nil if !level.is_a?(Integer)
61
+
62
+ # Set the logging level on all "vagrant" namespaced
63
+ # logs as long as we have a valid level.
64
+ if level
65
+ logger = Log4r::Logger.new("vagrant_fifo")
66
+ logger.outputters = Log4r::Outputter.stderr
67
+ logger.level = level
68
+ logger = nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,50 @@
1
+ require "log4r"
2
+ require "vagrant"
3
+
4
+ module VagrantPlugins
5
+ module Fifo
6
+ class Provider < Vagrant.plugin("2", :provider)
7
+ def initialize(machine)
8
+ @machine = machine
9
+ end
10
+
11
+ def action(name)
12
+ # Attempt to get the action method from the Action class if it
13
+ # exists, otherwise return nil to show that we don't support the
14
+ # given action.
15
+ action_method = "action_#{name}"
16
+ return Action.send(action_method) if Action.respond_to?(action_method)
17
+ nil
18
+ end
19
+
20
+ def ssh_info
21
+ # Run a custom action called "read_ssh_info" which does what it
22
+ # says and puts the resulting SSH info into the `:machine_ssh_info`
23
+ # key in the environment.
24
+ env = @machine.action("read_ssh_info")
25
+ env[:machine_ssh_info]
26
+ end
27
+
28
+ def state
29
+ # Run a custom action we define called "read_state" which does
30
+ # what it says. It puts the state in the `:machine_state_id`
31
+ # key in the environment.
32
+ env = @machine.action("read_state")
33
+
34
+ state_id = env[:machine_state_id]
35
+
36
+ # Get the short and long description
37
+ short = I18n.t("vagrant_fifo.states.short_#{state_id}")
38
+ long = I18n.t("vagrant_fifo.states.long_#{state_id}")
39
+
40
+ # Return the MachineState object
41
+ Vagrant::MachineState.new(state_id, short, long)
42
+ end
43
+
44
+ def to_s
45
+ id = @machine.id.nil? ? "new" : @machine.id
46
+ "Fifo (#{id})"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ module VagrantPlugins
2
+ module Fifo
3
+ module Util
4
+ class Timer
5
+ # A basic utility method that times the execution of the given
6
+ # block and returns it.
7
+ def self.time
8
+ start_time = Time.now.to_f
9
+ yield
10
+ end_time = Time.now.to_f
11
+
12
+ end_time - start_time
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Fifo
3
+ VERSION = "0.2.0"
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ require "pathname"
2
+
3
+ require "vagrant-fifo/plugin"
4
+
5
+ module VagrantPlugins
6
+ module Fifo
7
+ lib_path = Pathname.new(File.expand_path("../vagrant-fifo", __FILE__))
8
+ autoload :Action, lib_path.join("action")
9
+ autoload :Errors, lib_path.join("errors")
10
+
11
+ # This returns the path to the source of this plugin.
12
+ #
13
+ # @return [Pathname]
14
+ def self.source_root
15
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
16
+ end
17
+ end
18
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,65 @@
1
+ en:
2
+ vagrant_fifo:
3
+ already_created: |-
4
+ The machine is already created.
5
+ launching_instance: |-
6
+ Launching an instance with the following settings...
7
+ not_created: |-
8
+ Instance is not created. Please run `vagrant up` first.
9
+ ready: |-
10
+ Machine is booted and ready for use!
11
+ rsync_folder: |-
12
+ Rsyncing folder: %{hostpath} => %{guestpath}
13
+ terminating: |-
14
+ Terminating the instance...
15
+ waiting_for_ready: |-
16
+ Waiting for instance to become "ready"...
17
+ waiting_for_ssh: |-
18
+ Waiting for SSH to become available...
19
+ will_not_destroy: |-
20
+ The instance '%{name}' will not be destroyed, since the confirmation
21
+ was declined.
22
+
23
+ config:
24
+ fifo_username_required: |-
25
+ A Fifo Username must be specified via "fifo_username"
26
+ fifo_keyname_required: |-
27
+ A Fifo Keyname must be specified via "fifo_keyname"
28
+ fifo_keyfile_required: |-
29
+ A Fifo Keyfile must be specified via "fifo_keyfile"
30
+ fifo_api_url_required: |-
31
+ A Fifo Datacenter API endpoint must be specified via "fifo_api_url"
32
+ dataset_required: |-
33
+ A Fifo Dataset must be specified via "dataset"
34
+ node_name_required: |-
35
+ A Node Name must be specified via "node_name"
36
+ ssh_username_required: |-
37
+ An SSH username must be specified via "ssh_username"
38
+ ssh_private_key_path_required: |-
39
+ An SSH Private Key must be specified via "ssh_private_key_path"
40
+
41
+ errors:
42
+ fog_error: |-
43
+ There was an error talking to Fifo. The error message is shown
44
+ below:
45
+
46
+ %{message}
47
+ rsync_error: |-
48
+ There was an error when attemping to rsync a share folder.
49
+ Please inspect the error message below for more info.
50
+
51
+ Host path: %{hostpath}
52
+ Guest path: %{guestpath}
53
+ Error: %{stderr}
54
+
55
+ states:
56
+ short_not_created: |-
57
+ not created
58
+ long_not_created: |-
59
+ The Fifo instance is not created. Run `vagrant up` to create it.
60
+
61
+ short_running: |-
62
+ running
63
+ long_running: |-
64
+ The Fifo instance is running. To stop this machine, you can run
65
+ `vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
@@ -0,0 +1,19 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "vagrant-fifo/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "vagrant-fifo"
6
+ s.version = VagrantPlugins::Fifo::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = [ "Sean OMeara", "Brian Akins" ]
9
+ s.email = [ "someara@opscode.com", "brian@akins.org" ]
10
+ s.homepage = "http://www.vagrantup.com"
11
+ s.summary = "Enables Vagrant to manage machines in Fifo cloud and SDC"
12
+ s.description = "Enables Vagrant to manage machines in Fifo cloud and SDC"
13
+
14
+ s.add_dependency "project-fifo-ruby"
15
+
16
+ s.files = `git ls-files`.split($/)
17
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ s.require_path = 'lib'
19
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-fifo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sean OMeara
9
+ - Brian Akins
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-06-22 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: project-fifo-ruby
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ description: Enables Vagrant to manage machines in Fifo cloud and SDC
32
+ email:
33
+ - someara@opscode.com
34
+ - brian@akins.org
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - .gitignore
40
+ - Gemfile
41
+ - LICENSE.txt
42
+ - README.md
43
+ - Rakefile
44
+ - example_box/README.md
45
+ - example_box/Vagrantfile
46
+ - example_box/metadata.json
47
+ - lib/vagrant-fifo.rb
48
+ - lib/vagrant-fifo/action.rb
49
+ - lib/vagrant-fifo/action/connect_fifo.rb
50
+ - lib/vagrant-fifo/action/is_created.rb
51
+ - lib/vagrant-fifo/action/message_already_created.rb
52
+ - lib/vagrant-fifo/action/message_not_created.rb
53
+ - lib/vagrant-fifo/action/message_will_not_destroy.rb
54
+ - lib/vagrant-fifo/action/read_ssh_info.rb
55
+ - lib/vagrant-fifo/action/read_state.rb
56
+ - lib/vagrant-fifo/action/run_instance.rb
57
+ - lib/vagrant-fifo/action/sync_folders.rb
58
+ - lib/vagrant-fifo/action/terminate_instance.rb
59
+ - lib/vagrant-fifo/action/timed_provision.rb
60
+ - lib/vagrant-fifo/action/warn_networks.rb
61
+ - lib/vagrant-fifo/config.rb
62
+ - lib/vagrant-fifo/errors.rb
63
+ - lib/vagrant-fifo/plugin.rb
64
+ - lib/vagrant-fifo/provider.rb
65
+ - lib/vagrant-fifo/util/timer.rb
66
+ - lib/vagrant-fifo/version.rb
67
+ - locales/en.yml
68
+ - vagrant-fifo.gemspec
69
+ homepage: http://www.vagrantup.com
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.23
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: Enables Vagrant to manage machines in Fifo cloud and SDC
93
+ test_files: []
94
+ has_rdoc: