vagrant-seil 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6df8384c371512adffd1673a017f41d11894305c
4
+ data.tar.gz: 2188755e89d5b61461152fcaac92c1f682c6efaf
5
+ SHA512:
6
+ metadata.gz: 6934fa37eb650ae34b51e3a069a4f9de1093bba5cac9dbef09ffcda5e459fc52526cb3789762842c68d33b790250c7424b0daa4d37d8b32712072e9c16de233c
7
+ data.tar.gz: d3499b55922f91d94dcec437e070e7b18817440707543561ab886a28dccb5a47c63a3cc0176292f9ebff90e10a7209afe6e2f4e6c4a30cbc25f92fed4fd5d14e
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development do
4
+ gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git", :tag => 'v1.7.2'
5
+ end
6
+
7
+ group :plugins do
8
+ gem "vagrant-seil", path: "."
9
+ end
@@ -0,0 +1,15 @@
1
+ require "pathname"
2
+
3
+ require "vagrant-seil/plugin"
4
+ require "vagrant-seil/version"
5
+
6
+ module VagrantPlugins
7
+ module Seil
8
+ lib_path = Pathname.new(File.expand_path("../vagrant-seil", __FILE__))
9
+ autoload :Errors, lib_path.join("errors")
10
+
11
+ def self.source_root
12
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module VagrantPlugins
2
+ module Seil
3
+ module Cap
4
+ class ChangeHostName
5
+ def self.change_host_name(machine, name)
6
+ #machine.communicate.execute("hostname #{name}")
7
+ true
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,34 @@
1
+ require 'ipaddr'
2
+
3
+ module VagrantPlugins
4
+ module Seil
5
+ module Cap
6
+ class ConfigureNetworks
7
+ def self.configure_networks(machine, networks)
8
+ # [{:type=>:static,
9
+ # :adapter_ip=>"192.168.50.1",
10
+ # :ip=>"192.168.50.2",
11
+ # :netmask=>"255.255.255.0",
12
+ # :auto_config=>true,
13
+ # :interface=>1},
14
+ # {:type=>:dhcp,
15
+ # :use_dhcp_assigned_default_route=>false,
16
+ # :auto_config=>true,
17
+ # :interface=>2}]
18
+ machine.communicate.tap do |comm|
19
+ networks.each { |net|
20
+ if net[:type] == :static
21
+ ifname = "lan#{net[:interface]}"
22
+ addr = net[:ip]
23
+ plen = IPAddr.new(net[:netmask]).to_i.to_s(2).count("1")
24
+ comm.execute("interface #{ifname} address #{addr}/#{plen}")
25
+ else
26
+ machine.env.ui.warn "SEIL cannot have more than one DHCP interface"
27
+ end
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ require "vagrant/util/shell_quote"
2
+
3
+ module VagrantPlugins
4
+ module Seil
5
+ module Cap
6
+ class InsertPublicKey
7
+ def self.insert_public_key(machine, contents)
8
+ contents = contents.split.first(2).join(" ")
9
+ contents = Vagrant::Util::ShellQuote.escape(contents, "'")
10
+ machine.communicate.tap do |comm|
11
+ comm.execute("sshd authorized-key admin add VAGRANT #{contents}")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module VagrantPlugins
2
+ module Seil
3
+ module Cap
4
+ class MountVirtualBoxSharedFolder
5
+ def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
6
+ machine.ui.detail I18n.t("vagrant_seil.no_synced_folders")
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ module VagrantPlugins
2
+ module Seil
3
+ module Cap
4
+ class RemovePublicKey
5
+ def self.remove_public_key(machine, contents)
6
+ machine.communicate.tap do |comm|
7
+ keytype, pubkey = contents.split.first(2)
8
+ name = nil
9
+
10
+ comm.execute("show config sshd") do |type, text|
11
+ if type == :stdout
12
+ if text =~ /^sshd authorized-key admin add (\S+) (\S+) (\S+)/
13
+ if keytype == $2 and pubkey == $3
14
+ name = $1
15
+ end
16
+ end
17
+ end
18
+ end
19
+ if name
20
+ comm.execute("sshd authorized-key admin delete #{name}")
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,247 @@
1
+ require "log4r"
2
+
3
+ require Vagrant.source_root.join("plugins/communicators/ssh/communicator")
4
+
5
+ module VagrantPlugins
6
+ module Seil
7
+ class Communicator < VagrantPlugins::CommunicatorSSH::Communicator
8
+ def initialize(machine)
9
+ super
10
+ @logger.info("SEIL: Communicator#initialize")
11
+ end
12
+
13
+ def ready?
14
+ @logger.info("SEIL: Communicator#ready?")
15
+ super
16
+ end
17
+
18
+ def execute(command, **opts, &block)
19
+ @logger.info("SEIL: execute => command=#{command.inspect} opts=#{opts.inspect} block=#{block.inspect}")
20
+ super
21
+ end
22
+
23
+ def from_stdin(command, text, **opts)
24
+ @logger.debug("from_stdin: #{command}")
25
+ connect do |connection|
26
+ stdout = ""
27
+
28
+ channel = connection.open_channel do |ch|
29
+ ch.send_channel_request "shell" do |ch, _|
30
+ ch.on_data do |ch, data|
31
+ stdout << data
32
+ #@logger.debug("stdout=#{stdout.inspect}")
33
+ @logger.debug("stdout << #{data.inspect}")
34
+ ch.eof! if stdout =~ /^00\h{6}: /
35
+ end
36
+
37
+ @logger.debug("SEIL: command=#{command}")
38
+ ch.send_data "#{command.strip}\n"
39
+ @logger.debug("SEIL: text=#{text}")
40
+ ch.send_data "#{text.strip}\n"
41
+ ch.send_data "."
42
+ end
43
+ end
44
+
45
+ # Wait for the channel to complete
46
+ begin
47
+ channel.wait
48
+ rescue Errno::ECONNRESET, IOError
49
+ @logger.info(
50
+ "SSH connection unexpected closed. Assuming reboot or something.")
51
+ exit_status = 0
52
+ pty = false
53
+ rescue Net::SSH::ChannelOpenFailed
54
+ raise Vagrant::Errors::SSHChannelOpenFail
55
+ rescue Net::SSH::Disconnect
56
+ raise Vagrant::Errors::SSHDisconnected
57
+ end
58
+ end
59
+ end
60
+
61
+ # XXX: Copied from SSH communicator (of Vagrant version 1.7.2)
62
+ # Executes the command on an SSH connection within a login shell.
63
+ def shell_execute(connection, command, **opts)
64
+ @logger.info("SEIL: shell_execute command=#{command.inspect}")
65
+
66
+ opts = {
67
+ sudo: false,
68
+ shell: nil
69
+ }.merge(opts)
70
+
71
+ sudo = opts[:sudo]
72
+ shell = opts[:shell]
73
+
74
+ @logger.info("Execute: #{command} (sudo=#{sudo.inspect})")
75
+ exit_status = nil
76
+
77
+ # Determine the shell to execute. Prefer the explicitly passed in shell
78
+ # over the default configured shell. If we are using `sudo` then we
79
+ # need to wrap the shell in a `sudo` call.
80
+ #shell_cmd = @machine.config.ssh.shell
81
+ #shell_cmd = shell if shell
82
+ #shell_cmd = "sudo -E -H #{shell_cmd}" if sudo
83
+ shell_cmd = ""
84
+ @logger.info("SEIL: shell_cmd=#{shell_cmd}")
85
+ # connection is Net::SSH::Connection::Session
86
+
87
+ # These variables are used to scrub PTY output if we're in a PTY
88
+ pty = false
89
+ pty_stdout = ""
90
+
91
+ # Open the channel so we can execute or command
92
+ channel = connection.open_channel do |ch|
93
+ @logger.info("SEIL: @machine.config.ssh.pty=#{@machine.config.ssh.pty}")
94
+ if @machine.config.ssh.pty
95
+ ch.request_pty do |ch2, success|
96
+ pty = success && command != ""
97
+
98
+ if success
99
+ @logger.debug("pty obtained for connection")
100
+ else
101
+ @logger.warn("failed to obtain pty, will try to continue anyways")
102
+ end
103
+ end
104
+ end
105
+
106
+ #ch.exec(shell_cmd) do |ch2, _|
107
+ command = "exit" if command.strip == ""
108
+ ch.exec(command) do |ch2, _|
109
+ # Setup the channel callbacks so we can get data and exit status
110
+ ch2.on_data do |ch3, data|
111
+ # Filter out the clear screen command
112
+ data = remove_ansi_escape_codes(data)
113
+ @logger.debug("stdout: #{data}")
114
+ data.gsub!(/^\h{8}: /, "")
115
+ if pty
116
+ pty_stdout << data
117
+ else
118
+ yield :stdout, data if block_given?
119
+ end
120
+ end
121
+
122
+ ch2.on_extended_data do |ch3, type, data|
123
+ # Filter out the clear screen command
124
+ data = remove_ansi_escape_codes(data)
125
+ @logger.debug("stderr: #{data}")
126
+ yield :stderr, data if block_given?
127
+ end
128
+
129
+ ch2.on_request("exit-status") do |ch3, data|
130
+ exit_status = data.read_long
131
+ @logger.debug("Exit status: #{exit_status}")
132
+
133
+ # Close the channel, since after the exit status we're
134
+ # probably done. This fixes up issues with hanging.
135
+ channel.close
136
+ end
137
+
138
+ # Set the terminal
139
+ #ch2.send_data "export TERM=vt100\n"
140
+
141
+ # Set SSH_AUTH_SOCK if we are in sudo and forwarding agent.
142
+ # This is to work around often misconfigured boxes where
143
+ # the SSH_AUTH_SOCK env var is not preserved.
144
+ if @connection_ssh_info[:forward_agent] && sudo
145
+ auth_socket = ""
146
+ execute("echo; printf $SSH_AUTH_SOCK") do |type, data|
147
+ if type == :stdout
148
+ auth_socket += data
149
+ end
150
+ end
151
+
152
+ if auth_socket != ""
153
+ # Make sure we only read the last line which should be
154
+ # the $SSH_AUTH_SOCK env var we printed.
155
+ auth_socket = auth_socket.split("\n").last.chomp
156
+ end
157
+
158
+ if auth_socket == ""
159
+ @logger.warn("No SSH_AUTH_SOCK found despite forward_agent being set.")
160
+ else
161
+ @logger.info("Setting SSH_AUTH_SOCK remotely: #{auth_socket}")
162
+ ch2.send_data "export SSH_AUTH_SOCK=#{auth_socket}\n"
163
+ end
164
+ end
165
+
166
+ #ch2.send_data "#{command}\n".force_encoding('ASCII-8BIT')
167
+
168
+ # Output the command. If we're using a pty we have to do
169
+ # a little dance to make sure we get all the output properly
170
+ # without the cruft added from pty mode.
171
+ @logger.info("SEIL: pty = #{pty}")
172
+ if pty
173
+ data = "stty raw -echo\n"
174
+ data += "export PS1=\n"
175
+ data += "export PS2=\n"
176
+ data += "export PROMPT_COMMAND=\n"
177
+ data += "printf #{PTY_DELIM_START}\n"
178
+ data += "#{command}\n"
179
+ data += "exitcode=$?\n"
180
+ data += "printf #{PTY_DELIM_END}\n"
181
+ data += "exit $exitcode\n"
182
+ data = data.force_encoding('ASCII-8BIT')
183
+ ch2.send_data data
184
+ else
185
+ ch2.send_data "#{command}\n".force_encoding('ASCII-8BIT')
186
+ # Remember to exit or this channel will hang open
187
+ ch2.send_data "exit\n"
188
+ end
189
+
190
+ # Send eof to let server know we're done
191
+ ch2.eof!
192
+ end
193
+ end
194
+
195
+ begin
196
+ keep_alive = nil
197
+
198
+ if @machine.config.ssh.keep_alive
199
+ # Begin sending keep-alive packets while we wait for the script
200
+ # to complete. This avoids connections closing on long-running
201
+ # scripts.
202
+ keep_alive = Thread.new do
203
+ loop do
204
+ sleep 5
205
+ @logger.debug("Sending SSH keep-alive...")
206
+ connection.send_global_request("keep-alive@openssh.com")
207
+ end
208
+ end
209
+ end
210
+
211
+ # Wait for the channel to complete
212
+ begin
213
+ channel.wait
214
+ rescue Errno::ECONNRESET, IOError
215
+ @logger.info(
216
+ "SSH connection unexpected closed. Assuming reboot or something.")
217
+ exit_status = 0
218
+ pty = false
219
+ rescue Net::SSH::ChannelOpenFailed
220
+ raise Vagrant::Errors::SSHChannelOpenFail
221
+ rescue Net::SSH::Disconnect
222
+ raise Vagrant::Errors::SSHDisconnected
223
+ end
224
+ ensure
225
+ # Kill the keep-alive thread
226
+ keep_alive.kill if keep_alive
227
+ end
228
+
229
+ # If we're in a PTY, we now finally parse the output
230
+ if pty
231
+ @logger.debug("PTY stdout: #{pty_stdout}")
232
+ if !pty_stdout.include?(PTY_DELIM_START) || !pty_stdout.include?(PTY_DELIM_END)
233
+ @logger.error("PTY stdout doesn't include delims")
234
+ raise Vagrant::Errors::SSHInvalidShell.new
235
+ end
236
+
237
+ data = pty_stdout[/.*#{PTY_DELIM_START}(.*?)#{PTY_DELIM_END}/m, 1]
238
+ @logger.debug("PTY stdout parsed: #{data}")
239
+ yield :stdout, data if block_given?
240
+ end
241
+
242
+ # Return the final exit status
243
+ return exit_status
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,28 @@
1
+ module VagrantPlugins
2
+ module Seil
3
+ class Config < Vagrant.plugin("2", :config)
4
+ #attr_accessor :halt_timeout
5
+ attr_accessor :config
6
+ attr_accessor :function_key
7
+ attr_accessor :starter_key
8
+
9
+ def initialize
10
+ @config = UNSET_VALUE
11
+ @function_key = UNSET_VALUE
12
+ @starter_key = UNSET_VALUE
13
+ end
14
+
15
+ def finalize!
16
+ @config = nil if @config == UNSET_VALUE
17
+ @function_key = nil if @function_key == UNSET_VALUE
18
+ @starter_key = nil if @starter_key == UNSET_VALUE
19
+ end
20
+
21
+ def validate(machine)
22
+ errors = _detected_errors
23
+
24
+ { "SEIL provisioner" => errors }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require 'vagrant/util/template_renderer'
2
+
3
+ module VagrantPlugins
4
+ module Seil
5
+ class Guest < Vagrant.plugin("2", :guest)
6
+ def detect?(machine)
7
+ machine.communicate.execute("show system")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,79 @@
1
+ require "log4r"
2
+ require "vagrant"
3
+
4
+ module VagrantPlugins
5
+ module Seil
6
+ class Plugin < Vagrant.plugin("2")
7
+ name "SEIL/x86 guest"
8
+ description "SEIL/x86 guest support."
9
+
10
+ guest("seil") do
11
+ require File.expand_path("../guest", __FILE__)
12
+ Guest
13
+ end
14
+
15
+ #guest_capability("seil", "change_host_name") do
16
+ # require_relative "cap/change_host_name"
17
+ # Cap::ChangeHostName
18
+ #end
19
+
20
+ guest_capability("seil", "mount_virtualbox_shared_folder") do
21
+ require_relative "cap/mount_virtualbox_shared_folder"
22
+ Cap::MountVirtualBoxSharedFolder
23
+ end
24
+
25
+ config(:seil, :provisioner) do
26
+ require_relative "config"
27
+ Config
28
+ end
29
+
30
+ provisioner "seil" do
31
+ setup_i18n
32
+ #setup_logging
33
+
34
+ require_relative "provisioner"
35
+ Provisioner
36
+ end
37
+
38
+ communicator(:seil_ssh) do
39
+ require_relative "communicator"
40
+ Communicator
41
+ end
42
+
43
+ guest_capability("seil", "configure_networks") do
44
+ require_relative "cap/configure_networks"
45
+ Cap::ConfigureNetworks
46
+ end
47
+
48
+ guest_capability("seil", "insert_public_key") do
49
+ require_relative "cap/insert_public_key"
50
+ Cap::InsertPublicKey
51
+ end
52
+
53
+ guest_capability("seil", "remove_public_key") do
54
+ require_relative "cap/remove_public_key"
55
+ Cap::RemovePublicKey
56
+ end
57
+
58
+ def self.setup_i18n
59
+ I18n.load_path << File.expand_path("locales/en.yml", Seil.source_root)
60
+ I18n.reload!
61
+ end
62
+
63
+ #action_hook(:install_keys, Plugin::ALL_ACTIONS) do |hook|
64
+ # require_relative "action/install_keys"
65
+ # hook.before(Vagrant::Action::Builtin::Provision, Action::InstallKeys)
66
+ #end
67
+
68
+ # guest_capability("freebsd", "halt") do
69
+ # require_relative "cap/halt"
70
+ # Cap::Halt
71
+ # end
72
+
73
+ # guest_capability("freebsd", "mount_nfs_folder") do
74
+ # require_relative "cap/mount_nfs_folder"
75
+ # Cap::MountNFSFolder
76
+ # end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,72 @@
1
+ require "ipaddr"
2
+ require "vagrant/util/template_renderer"
3
+
4
+ module VagrantPlugins
5
+ module Seil
6
+ class Provisioner < Vagrant.plugin("2", :provisioner)
7
+ def provision
8
+ @machine.communicate.tap do |comm|
9
+ if config.starter_key
10
+ comm.from_stdin("install-key from stdin", config.starter_key)
11
+ end
12
+
13
+ if config.function_key
14
+ comm.from_stdin("install-key from stdin", config.function_key)
15
+ end
16
+
17
+ if config.config
18
+ hostname = @machine.config.vm.hostname || "vagrant"
19
+ header = "hostname #{hostname}\n"
20
+ header += <<-EOS
21
+ interface lan0 add dhcp
22
+ encrypted-password admin *
23
+ encrypted-password user *
24
+ EOS
25
+
26
+ # [:private_network,
27
+ # {:ip=>"192.168.50.254",
28
+ # :protocol=>"tcp",
29
+ # :id=>"83fe7d32-3e29-63b1-7f24-4c3b9a42839c"}]
30
+ ifidx = 1
31
+ @machine.config.vm.networks.each { |type, netopts|
32
+ next if type != :public_network && type != :private_network
33
+
34
+ ifname = "lan#{ifidx}"
35
+ ifidx += 1
36
+ addr = netopts[:ip]
37
+ if netopts[:netmask]
38
+ plen = IPAddr.new(netopts[:netmask]).to_i.to_s(2).count("1")
39
+ else
40
+ plen = 24
41
+ end
42
+ header += "interface #{ifname} add #{addr}/#{plen}\n"
43
+ }
44
+
45
+ comm.execute("show config sshd") do |type, text|
46
+ header << text if type == :stdout
47
+ end
48
+
49
+ text = header + config.config
50
+ text.gsub!(/^ +/, "")
51
+ text.gsub!(/ +$/, "")
52
+
53
+ @machine.ui.detail I18n.t("vagrant_seil.load_from")
54
+ comm.from_stdin("load-from stdin", text)
55
+
56
+ saved = false
57
+ comm.execute("show key") do |type, text|
58
+ if type == :stdout and text.include? "Function Key"
59
+ @machine.ui.detail I18n.t("vagrant_seil.save_to_flashrom")
60
+ comm.execute("save-to flashrom")
61
+ saved = true
62
+ end
63
+ end
64
+ unless saved
65
+ @machine.ui.warn I18n.t("vagrant_seil.not_saved")
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Seil
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ en:
2
+ vagrant_seil:
3
+ load_from: |-
4
+ load-from Vagrant...
5
+ no_synced_folders: |-
6
+ nothing happens - vagrant-seil does not support synced folders
7
+ not_saved: |-
8
+ Warning: configuration is not saved because function key is not installed.
9
+ save_to_flashrom: |-
10
+ save-to flashrom...
@@ -0,0 +1,18 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'vagrant-seil/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "vagrant-seil"
7
+ spec.version = VagrantPlugins::Seil::VERSION
8
+ spec.authors = ["Tomoyuki Sahara"]
9
+ spec.email = ["tsahara@iij.ad.jp"]
10
+ spec.description = %q{Vagrant Plugin for SEIL/x86.}
11
+ spec.summary = %q{Vagrant Plugin for SEIL/x86.}
12
+ spec.homepage = "https://github.com/iij/vagrant-seil"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files Gemfile lib locales *.gemspec`.split($/)
16
+ #spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-seil
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tomoyuki Sahara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Vagrant Plugin for SEIL/x86.
14
+ email:
15
+ - tsahara@iij.ad.jp
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - Gemfile
21
+ - lib/vagrant-seil.rb
22
+ - lib/vagrant-seil/cap/change_host_name.rb
23
+ - lib/vagrant-seil/cap/configure_networks.rb
24
+ - lib/vagrant-seil/cap/insert_public_key.rb
25
+ - lib/vagrant-seil/cap/mount_virtualbox_shared_folder.rb
26
+ - lib/vagrant-seil/cap/remove_public_key.rb
27
+ - lib/vagrant-seil/communicator.rb
28
+ - lib/vagrant-seil/config.rb
29
+ - lib/vagrant-seil/guest.rb
30
+ - lib/vagrant-seil/plugin.rb
31
+ - lib/vagrant-seil/provisioner.rb
32
+ - lib/vagrant-seil/version.rb
33
+ - locales/en.yml
34
+ - vagrant-seil.gemspec
35
+ homepage: https://github.com/iij/vagrant-seil
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.2.2
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Vagrant Plugin for SEIL/x86.
59
+ test_files: []