Commit e391d9ba09781f131e39246de9fb425e36895dd7
0 parents
Initial commit
The LXD provider load a box definition, downloads the corresponding image, create a container and prepares it for vagrant ssh. So vagrant up brings the container to live including managed bridge networking and vagrant ssh enters the container.
Showing
24 changed files
with
748 additions
and
0 deletions
.gitignore
0 → 100644
Gemfile
0 → 100644
README.md
0 → 100644
1 | +# Vagrant::Lxd | |
2 | + | |
3 | +Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/vagrant/lxd`. To experiment with that code, run `bin/console` for an interactive prompt. | |
4 | + | |
5 | +TODO: Delete this and the text above, and describe your gem | |
6 | + | |
7 | +## Installation | |
8 | + | |
9 | +Add this line to your application's Gemfile: | |
10 | + | |
11 | +```ruby | |
12 | +gem 'vagrant-lxd' | |
13 | +``` | |
14 | + | |
15 | +And then execute: | |
16 | + | |
17 | + $ bundle | |
18 | + | |
19 | +Or install it yourself as: | |
20 | + | |
21 | + $ gem install vagrant-lxd | |
22 | + | |
23 | +## Usage | |
24 | + | |
25 | +TODO: Write usage instructions here | |
26 | + | |
27 | +## Development | |
28 | + | |
29 | +After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. | |
30 | + | |
31 | +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). | |
32 | + | |
33 | +## Contributing | |
34 | + | |
35 | +Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/vagrant-lxd. | |
36 | + | ... | ... |
Rakefile
0 → 100644
bin/console
0 → 100755
1 | +#!/usr/bin/env ruby | |
2 | + | |
3 | +require "bundler/setup" | |
4 | +require "vagrant/lxd" | |
5 | + | |
6 | +# You can add fixtures and/or initialization code here to make experimenting | |
7 | +# with your gem easier. You can also use a different console, if you like. | |
8 | + | |
9 | +# (If you use this, don't forget to add pry to your Gemfile!) | |
10 | +# require "pry" | |
11 | +# Pry.start | |
12 | + | |
13 | +require "irb" | |
14 | +IRB.start | ... | ... |
bin/setup
0 → 100755
example_box/README.md
0 → 100644
1 | +# Vagrant LXD Example Box | |
2 | + | |
3 | +Vagrant providers each require a custom provider-specific box format. | |
4 | +This folder shows the example contents of a box for the `lxd` provider. | |
5 | +To turn this into a box: | |
6 | + | |
7 | +``` | |
8 | +$ tar cvzf lxd.box ./metadata.json ./vagrant.pub | |
9 | +``` | |
10 | + | |
11 | +The `lxd` provider right now just uses the default lxd images provided | |
12 | +by the lxd images: remote. Upon start these will be provisioned with an | |
13 | +vagrant ssh user and and the unsafe common pubkey of vagrant and | |
14 | +sshd will be enabled. | |
15 | + | |
16 | +Well, at least thats the idea for now. | ... | ... |
example_box/metadata.json
0 → 100644
example_box/vagrant.pub
0 → 100644
1 | +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key | ... | ... |
gentoo.json
0 → 100644
1 | +{ | |
2 | + "name": "lxd/gentoo", | |
3 | + "description": "The latest gentoo LXD image.", | |
4 | + "versions": [ | |
5 | + { | |
6 | + "version": "0.0.1", | |
7 | + "providers": [ | |
8 | + { | |
9 | + "name": "lxd", | |
10 | + "url": "file:///data/ghopp/projects/vagrant/vagrant-lxd/gentoo_001_lxd.box", | |
11 | + "checksum_type": "sha1", | |
12 | + "checksum": "4f3d7bfe034fe9fb82179992fdc6803b6f96abfb" | |
13 | + } | |
14 | + ] | |
15 | + } | |
16 | + ] | |
17 | +} | ... | ... |
gentoo_001_lxd.box
0 → 100644
No preview for this file type
lib/vagrant/lxd.rb
0 → 100644
lib/vagrant/lxd/action.rb
0 → 100644
1 | +require 'json' | |
2 | +require 'log4r' | |
3 | + | |
4 | +require 'vagrant/action/builder' | |
5 | + | |
6 | +module Vagrant | |
7 | + module Lxd | |
8 | + module Action | |
9 | + action_root = Pathname.new(File.expand_path("../action", __FILE__)) | |
10 | + autoload :Create, action_root.join("create") | |
11 | + autoload :EnsureImage, action_root.join("ensure_image") | |
12 | + autoload :EnsureSsh, action_root.join("ensure_ssh") | |
13 | + autoload :EnsureStarted, action_root.join("ensure_started") | |
14 | + autoload :Network, action_root.join("network") | |
15 | + | |
16 | + include Vagrant::Action::Builtin | |
17 | + | |
18 | + # This action boots the VM, assuming the VM is in a state that requires | |
19 | + # a bootup (i.e. not saved). | |
20 | + def self.action_up | |
21 | + Vagrant::Action::Builder.new.tap do |b| | |
22 | + b.use ConfigValidate | |
23 | + b.use Call, IsState, :not_created do |env, b2| | |
24 | + # If the VM is NOT created yet, then do the setup steps | |
25 | + if env[:result] | |
26 | + b2.use HandleBox | |
27 | + b2.use EnsureImage | |
28 | + b2.use Network | |
29 | + b2.use Create | |
30 | + end | |
31 | + end | |
32 | + b.use action_start | |
33 | + b.use EnsureSsh | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + def self.action_start | |
38 | + Vagrant::Action::Builder.new.tap do |b| | |
39 | + b.use EnsureStarted | |
40 | + end | |
41 | + end | |
42 | + | |
43 | + def self.action_ssh | |
44 | + Vagrant::Action::Builder.new.tap do |b| | |
45 | + b.use SSHExec | |
46 | + end | |
47 | + end | |
48 | + end | |
49 | + end | |
50 | +end | |
51 | + | |
52 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/action/create.rb
0 → 100644
1 | +module Vagrant | |
2 | + module Lxd | |
3 | + module Action | |
4 | + class Create | |
5 | + def initialize(app, env) | |
6 | + @app = app | |
7 | + @logger = Log4r::Logger.new("vagrant::lxd::action::create") | |
8 | + end | |
9 | + | |
10 | + def call(env) | |
11 | + driver = env[:machine].provider.driver | |
12 | + | |
13 | + if driver.container? | |
14 | + env[:ui].info "--- Container fount ---", :prefix => false | |
15 | + else | |
16 | + env[:ui].info "--- Create #{driver.name} ---", :prefix => false | |
17 | + driver.create | |
18 | + env[:ui].info "--- #{driver.name} created ---", :prefix => false | |
19 | + end | |
20 | + | |
21 | + @app.call(env) | |
22 | + end | |
23 | + end | |
24 | + end | |
25 | + end | |
26 | +end | |
27 | + | |
28 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/action/ensure_image.rb
0 → 100644
1 | +module Vagrant | |
2 | + module Lxd | |
3 | + module Action | |
4 | + class EnsureImage | |
5 | + def initialize(app, env) | |
6 | + @app = app | |
7 | + @logger = Log4r::Logger.new("vagrant::lxd::action::ensure_image") | |
8 | + end | |
9 | + | |
10 | + def call(env) | |
11 | + box = env[:machine].box | |
12 | + driver = env[:machine].provider.driver | |
13 | + | |
14 | + env[:ui].info "--- check image for #{env[:machine].name} ---", | |
15 | + :prefix => false | |
16 | + if driver.image? | |
17 | + env[:ui].info "--- Image found ---", :prefix => false | |
18 | + else | |
19 | + env[:ui].info "--- Image NOT found (downloading) ---", | |
20 | + :prefix => false | |
21 | + driver.get_image("images") | |
22 | + env[:ui].info "--- Image download done ---", :prefix => false | |
23 | + # TODO maybe we need to check again if the image really exists | |
24 | + # now. | |
25 | + end | |
26 | + | |
27 | + @app.call(env) | |
28 | + end | |
29 | + end | |
30 | + end | |
31 | + end | |
32 | +end | |
33 | + | |
34 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/action/ensure_ssh.rb
0 → 100644
1 | +module Vagrant | |
2 | + module Lxd | |
3 | + module Action | |
4 | + class EnsureSsh | |
5 | + def initialize(app, env) | |
6 | + @app = app | |
7 | + @logger = Log4r::Logger.new("vagrant::lxd::action::ensure_started") | |
8 | + end | |
9 | + | |
10 | + def call(env) | |
11 | + driver = env[:machine].provider.driver | |
12 | + | |
13 | + env[:ui].info "--- #{env[:machine].box.directory} ---", | |
14 | + :prefix => false | |
15 | + driver.vagrant_user | |
16 | + driver.enable_ssh | |
17 | + | |
18 | + @app.call(env) | |
19 | + end | |
20 | + end | |
21 | + end | |
22 | + end | |
23 | +end | |
24 | + | |
25 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/action/ensure_started.rb
0 → 100644
1 | +module Vagrant | |
2 | + module Lxd | |
3 | + module Action | |
4 | + class EnsureStarted | |
5 | + def initialize(app, env) | |
6 | + @app = app | |
7 | + @logger = Log4r::Logger.new("vagrant::lxd::action::ensure_started") | |
8 | + end | |
9 | + | |
10 | + def call(env) | |
11 | + driver = env[:machine].provider.driver | |
12 | + | |
13 | + if driver.state != :running | |
14 | + env[:ui].info "--- start #{driver.name} ---", | |
15 | + :prefix => false | |
16 | + driver.start | |
17 | + env[:ui].info "--- #{driver.name} started ---", | |
18 | + :prefix => false | |
19 | + else | |
20 | + env[:ui].info "--- #{driver.name} alreay running ---", | |
21 | + :prefix => false | |
22 | + end | |
23 | + | |
24 | + @app.call(env) | |
25 | + end | |
26 | + end | |
27 | + end | |
28 | + end | |
29 | +end | |
30 | + | |
31 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/action/network.rb
0 → 100644
1 | +module Vagrant | |
2 | + module Lxd | |
3 | + module Action | |
4 | + class Network | |
5 | + def initialize(app, env) | |
6 | + @app = app | |
7 | + @logger = Log4r::Logger.new("vagrant::lxd::action::network") | |
8 | + end | |
9 | + | |
10 | + def call(env) | |
11 | + ## | |
12 | + # Right now I ignore all network config for machines and connect | |
13 | + # them all to a single bridge called vagrantbr0. (Well the name | |
14 | + # is transparently used and may be changed if necessary. | |
15 | + # | |
16 | + env[:bridge] = env[:machine].provider.driver.bridge | |
17 | + | |
18 | + @app.call(env) | |
19 | + end | |
20 | + end | |
21 | + end | |
22 | + end | |
23 | +end | |
24 | + | |
25 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/command.rb
0 → 100644
lib/vagrant/lxd/driver.rb
0 → 100644
1 | +## | |
2 | +# Probably useful lxc commands | |
3 | +# - get mac address: | |
4 | +# lxc config get <container> volatile.eth0.hwaddr | |
5 | +# - get a json formated list of containers: | |
6 | +# lxc list --format=json -c ns4tS,volatile.eth0.hwaddr:MAC | |
7 | +# It seems that -c is ignored when json is user so: | |
8 | +# lxc list --format=json | |
9 | +# We care only about local containers... so ignore the remote. | |
10 | +# We might only want to list specific container started by vagrant, thus we | |
11 | +# should prefix each container name by the term 'vagrant_' and list only | |
12 | +# containers matching that pattern. | |
13 | +# lxc list vagrant- --format=json | |
14 | +# - The json above also seems to hold all the config information, anyway | |
15 | +# another way to show all config values for a given container in a more | |
16 | +# human readable form is: | |
17 | +# lxc config show <container> | |
18 | +# - Box/Image management is completely integrated with lxd. All image commands | |
19 | +# are: | |
20 | +# lxc image <something> | |
21 | +# The only thing we might need to keep information over is the image name or | |
22 | +# id to be used... here a remote might also be useful, to be able to use | |
23 | +# different image sources. But probably our box files will be quite simple. | |
24 | +# Anyway, i have not now completely figured out how box files work. | |
25 | +# | |
26 | +# This is pretty much all for now.... start, stop, init, etc. are left for | |
27 | +# later. | |
28 | +# One other thought... it might or might not be a good idea to connect all | |
29 | +# vagrant vms to the same bridge interface created by vagrant... anyway this | |
30 | +# should be configurable in some way. | |
31 | +# | |
32 | +# test this with e.g.: | |
33 | +# ~> bundel exec irb | |
34 | +# irb(main):001:0> load 'lxd.rb' | |
35 | +# => true | |
36 | +# irb(main):002:0> Vagrant::Lxd::Driver.new('vagrant-gentoo').vmdata | |
37 | +# | |
38 | +# General note: use pp to make the hash human readable. | |
39 | +# | |
40 | +# Network related commands: | |
41 | +# | |
42 | +# - Create a bridged network: | |
43 | +# lxc network create vagrantbr0 | |
44 | +# Another example: | |
45 | +# lxc network create vagrantbr0 ipv6.address=none ipv4.address=10.0.3.1/24 ipv4.nat=true | |
46 | +# - Attach network to container: | |
47 | +# lxc network attach vagrantbr0 <container> default eth0 | |
48 | +# | |
49 | +# Further things... right now gentoo specific | |
50 | +# | |
51 | +# - Create vagrant user: | |
52 | +# lxc exec <container> -- useradd vagrant | |
53 | +# - Set password: | |
54 | +# lxc exec <container> -- chpasswd <<<vagrant:vagrant | |
55 | +# - Enable sshd service: | |
56 | +# lxc exec <container> -- rc-update add sshd default | |
57 | +# - Start sshd service manually: | |
58 | +# lxc exec <container> -- /etc/init.d/sshd start | |
59 | +# | |
60 | +require 'json' | |
61 | +require 'log4r' | |
62 | +require 'yaml' | |
63 | + | |
64 | +require 'vagrant/util/retryable' | |
65 | + | |
66 | +module Vagrant | |
67 | + module Lxd | |
68 | + class Driver | |
69 | + include Vagrant::Util::Retryable | |
70 | + | |
71 | + attr_reader :name | |
72 | + | |
73 | + def initialize(machine) | |
74 | + @machine = machine | |
75 | + @name = "vagrant-#{machine.name}" | |
76 | + @logger = Log4r::Logger.new("vagrant::provider::lxd::driver") | |
77 | + | |
78 | + # This flag is used to keep track of interrupted state (SIGINT) | |
79 | + @interrupted = false | |
80 | + @image = machine.box.name.split("/")[1] if machine.box | |
81 | + bridge | |
82 | + end | |
83 | + | |
84 | + # Get all available images and their aliases | |
85 | + def images | |
86 | + data = JSON.parse(execute("image", "list", "--format=json")) | |
87 | + Hash[data.collect do |d| | |
88 | + d["aliases"].collect { |d2| [d2["name"], d] } | |
89 | + end.flatten(1)] | |
90 | + end | |
91 | + | |
92 | + def image? | |
93 | + images.key? @image | |
94 | + end | |
95 | + | |
96 | + # Get infos about all existing containers | |
97 | + def containers | |
98 | + data = JSON.parse(execute("list", "--format=json")) | |
99 | + Hash[data.collect { |d| [d["name"], d] }] | |
100 | + end | |
101 | + | |
102 | + def container? | |
103 | + containers.key? @name | |
104 | + end | |
105 | + | |
106 | + # This one will get infos about the managed container. | |
107 | + def container_data | |
108 | + containers[@name] | |
109 | + end | |
110 | + | |
111 | + def network | |
112 | + container_data["state"]["network"] | |
113 | + end | |
114 | + | |
115 | + def ipv4 | |
116 | + network["eth0"]["addresses"].select do |d| | |
117 | + d["family"] == "inet" | |
118 | + end[0]["address"] | |
119 | + end | |
120 | + | |
121 | + def state | |
122 | + return :not_created if not container? | |
123 | + return :stopped if not container_data["state"] | |
124 | + container_data["state"]["status"].downcase.to_sym | |
125 | + end | |
126 | + | |
127 | + def get_image(remote) | |
128 | + return if image? # image already exists | |
129 | + | |
130 | + args = [ | |
131 | + "image", | |
132 | + "copy", | |
133 | + "#{remote}:#{@image}", | |
134 | + "local:", | |
135 | + "--copy-aliases" | |
136 | + ] | |
137 | + | |
138 | + execute(*args) | |
139 | + end | |
140 | + | |
141 | + def create | |
142 | + # network could be also attached right here if it turns out to be | |
143 | + # a good idea. | |
144 | + execute("init", @image, @name, "-n", @bridge["name"]) | |
145 | + end | |
146 | + | |
147 | + def start | |
148 | + if state != :runnning | |
149 | + execute("start", @name) | |
150 | + end | |
151 | + end | |
152 | + | |
153 | + def bridge | |
154 | + while not @bridge do | |
155 | + begin | |
156 | + @bridge = YAML.load(execute("network", "show", "vagrantbr0")) | |
157 | + rescue | |
158 | + execute("network", "create", "vagrantbr0") | |
159 | + end | |
160 | + end | |
161 | + @bridge | |
162 | + end | |
163 | + | |
164 | + def vagrant_user | |
165 | + pwent = [] | |
166 | + while pwent.empty? do | |
167 | + begin | |
168 | + pwent = execute( | |
169 | + "exec", @name, "getent", "passwd", "vagrant" | |
170 | + ).split(":") | |
171 | + rescue | |
172 | + execute("exec", @name, "--", "useradd", "-m", "vagrant") | |
173 | + end | |
174 | + end | |
175 | + execute( | |
176 | + "file", | |
177 | + "push", | |
178 | + "--uid=#{pwent[2]}", | |
179 | + "--gid=#{pwent[3]}", | |
180 | + "--mode=0400", | |
181 | + "#{@machine.box.directory}/vagrant.pub", | |
182 | + "#{@name}/#{pwent[5]}/.ssh/authorized_keys" | |
183 | + ) | |
184 | + end | |
185 | + | |
186 | + def enable_ssh | |
187 | + begin | |
188 | + execute("exec", @name, "--", "rc-update", "add", "sshd", "default") | |
189 | + execute("exec", @name, "--", "/etc/init.d/sshd", "start") | |
190 | + rescue | |
191 | + end | |
192 | + end | |
193 | + | |
194 | + # Taken from Virtualbox provider and modified in some parts. | |
195 | + # Execute the given subcommand for Lxc and return the output. | |
196 | + def execute(*command, &block) | |
197 | + # Get the options hash if it exists | |
198 | + opts = {} | |
199 | + opts = command.pop if command.last.is_a?(Hash) | |
200 | + | |
201 | + tries = 0 | |
202 | + tries = 3 if opts[:retryable] | |
203 | + | |
204 | + # Variable to store our execution result | |
205 | + r = nil | |
206 | + | |
207 | + # Most probably retrying is of no use here... if the command does not | |
208 | + # work it most likely will not work for the second time anyway... | |
209 | + # I leave this because I guess that vagrant tries commands even it the | |
210 | + # container is not up and running at the current time. | |
211 | + retryable(on: Vagrant::Errors::ProviderNotUsable, tries: tries, sleep: 1) do | |
212 | + # Execute the command | |
213 | + r = raw(*command, &block) | |
214 | + | |
215 | + # If the command was a failure, then raise an exception that is | |
216 | + # nicely handled by Vagrant. | |
217 | + if r.exit_code != 0 | |
218 | + if @interrupted | |
219 | + @logger.info("Exit code != 0, but interrupted. Ignoring.") | |
220 | + else | |
221 | + raise Vagrant::Errors::ProviderNotUsable, | |
222 | + provider: 'lxd', | |
223 | + machine: @machine.name, | |
224 | + message: "\"#{command.inspect}\" failed", | |
225 | + command: command.inspect, | |
226 | + stderr: r.stderr, | |
227 | + stdout: r.stdout | |
228 | + end | |
229 | + end | |
230 | + end | |
231 | + | |
232 | + # Return the output, making sure to replace any Windows-style | |
233 | + # newlines with Unix-style. | |
234 | + r.stdout.gsub("\r\n", "\n") | |
235 | + end | |
236 | + | |
237 | + # Executes a command and returns the raw result object. | |
238 | + def raw(*command, &block) | |
239 | + int_callback = lambda do | |
240 | + @interrupted = true | |
241 | + | |
242 | + # We have to execute this in a thread due to trap contexts | |
243 | + # and locks. | |
244 | + Thread.new { @logger.info("Interrupted.") }.join | |
245 | + end | |
246 | + | |
247 | + # Append in the options for subprocess | |
248 | + command << { notify: [:stdout, :stderr] } | |
249 | + | |
250 | + Vagrant::Util::Busy.busy(int_callback) do | |
251 | + Vagrant::Util::Subprocess.execute('lxc', *command, &block) | |
252 | + end | |
253 | + rescue Vagrant::Util::Subprocess::LaunchError => e | |
254 | + raise Vagrant::Errors::ProviderNotUsable, | |
255 | + message: e.to_s | |
256 | + end | |
257 | + end | |
258 | + end | |
259 | +end | |
260 | + | |
261 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/plugin.rb
0 → 100644
1 | +## | |
2 | +# Test with something like: | |
3 | +# ~> bundle exec vagrant ls | |
4 | +# | |
5 | +module Vagrant | |
6 | + module Lxd | |
7 | + class Plugin < Vagrant.plugin('2') | |
8 | + name "Lxd" | |
9 | + | |
10 | + description <<-DESC | |
11 | + Vagrant LXD provider | |
12 | + DESC | |
13 | + | |
14 | + provider(:lxd, priority: 7) do | |
15 | + require File.expand_path("../provider", __FILE__) | |
16 | + Provider | |
17 | + end | |
18 | + | |
19 | + #config(:lxd, :provider) do | |
20 | + # require File.expand_path("../config", __FILE__) | |
21 | + # Config | |
22 | + #end | |
23 | + | |
24 | + #synced_folder(:virtualbox) do | |
25 | + # require File.expand_path("../synced_folder", __FILE__) | |
26 | + # SyncedFolder | |
27 | + #end | |
28 | + | |
29 | + command 'ls' do | |
30 | + require File.expand_path("../command", __FILE__) | |
31 | + Command | |
32 | + end | |
33 | + | |
34 | + autoload :Action, File.expand_path("../action", __FILE__) | |
35 | + end | |
36 | + end | |
37 | +end | |
38 | + | |
39 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/provider.rb
0 → 100644
1 | +require "log4r" | |
2 | + | |
3 | +module Vagrant | |
4 | + module Lxd | |
5 | + autoload :Driver, File.expand_path("../driver", __FILE__) | |
6 | + autoload :Action, File.expand_path("../action", __FILE__) | |
7 | + | |
8 | + class Provider < Vagrant.plugin('2', :provider) | |
9 | + attr_reader :driver | |
10 | + | |
11 | + def initialize(machine) | |
12 | + @logger = Log4r::Logger.new("vagrant::provider::lxd") | |
13 | + @machine = machine | |
14 | + @driver = Driver.new(@machine) | |
15 | + end | |
16 | + | |
17 | + # Returns the SSH info for accessing the LXD container. | |
18 | + def ssh_info | |
19 | + # If the VM is not running that we can't possibly SSH into it | |
20 | + return nil if state.id != :running | |
21 | + | |
22 | + # Return what we know. The host is always "127.0.0.1" because | |
23 | + # VirtualBox VMs are always local. The port we try to discover | |
24 | + # by reading the forwarded ports. | |
25 | + return { | |
26 | + host: @driver.ipv4, | |
27 | + port: "22" | |
28 | + } | |
29 | + end | |
30 | + | |
31 | + # Return the state of VirtualBox virtual machine by actually | |
32 | + # querying VBoxManage. | |
33 | + # | |
34 | + # @return [Symbol] | |
35 | + def state | |
36 | + # Determine the ID of the state here. | |
37 | + state_id = @driver.state | |
38 | + | |
39 | + # Translate into short/long descriptions | |
40 | + short = state_id.to_s.gsub("_", " ") | |
41 | + long = I18n.t("vagrant.commands.status.#{state_id}") | |
42 | + | |
43 | + # If we're not created, then specify the special ID flag | |
44 | + if state_id == :not_created | |
45 | + state_id = Vagrant::MachineState::NOT_CREATED_ID | |
46 | + end | |
47 | + | |
48 | + # Return the state | |
49 | + Vagrant::MachineState.new(state_id, short, long) | |
50 | + end | |
51 | + | |
52 | + # @see Vagrant::Plugin::V1::Provider#action | |
53 | + def action(name) | |
54 | + # Attempt to get the action method from the Action class if it | |
55 | + # exists, otherwise return nil to show that we don't support the | |
56 | + # given action. | |
57 | + action_method = "action_#{name}" | |
58 | + return Action.send(action_method) if Action.respond_to?(action_method) | |
59 | + nil | |
60 | + end | |
61 | + | |
62 | + def to_s | |
63 | + id = @machine.id ? @machine.id : "new VM" | |
64 | + "Lxd (#{id})" | |
65 | + end | |
66 | + end | |
67 | + end | |
68 | +end | |
69 | + | |
70 | +# vim: set et ts=2 sw=2: | ... | ... |
lib/vagrant/lxd/version.rb
0 → 100644
vagrant-lxd.gemspec
0 → 100644
1 | +# coding: utf-8 | |
2 | +lib = File.expand_path('../lib', __FILE__) | |
3 | +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |
4 | +require 'vagrant/lxd/version' | |
5 | + | |
6 | +Gem::Specification.new do |spec| | |
7 | + spec.name = "vagrant-lxd" | |
8 | + spec.version = Vagrant::Lxd::VERSION | |
9 | + spec.authors = ["Georg Hopp"] | |
10 | + spec.email = ["hopp@silpion.de"] | |
11 | + | |
12 | + spec.summary = %q{Vagrant LXD provider.} | |
13 | + spec.homepage = "https://somewhere.de/" | |
14 | + | |
15 | + # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' | |
16 | + # to allow pushing to a single host or delete this section to allow pushing to any host. | |
17 | + if spec.respond_to?(:metadata) | |
18 | + spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'" | |
19 | + else | |
20 | + raise "RubyGems 2.0 or newer is required to protect against " \ | |
21 | + "public gem pushes." | |
22 | + end | |
23 | + | |
24 | + spec.files = `git ls-files -z`.split("\x0").reject do |f| | |
25 | + f.match(%r{^(test|spec|features)/}) | |
26 | + end | |
27 | + spec.bindir = "exe" | |
28 | + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } | |
29 | + spec.require_paths = ["lib"] | |
30 | + | |
31 | + spec.add_development_dependency "bundler", "~> 1.13" | |
32 | + spec.add_development_dependency "rake", "~> 10.0" | |
33 | +end | ... | ... |
Please
register
or
login
to post a comment