Commit e391d9ba09781f131e39246de9fb425e36895dd7

Authored by Georg Hopp
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.
  1 +/.bundle/
  2 +/.yardoc
  3 +/Gemfile.lock
  4 +/_yardoc/
  5 +/coverage/
  6 +/doc/
  7 +/pkg/
  8 +/spec/reports/
  9 +/tmp/
  10 +/Vagrantfile
  1 +source 'https://rubygems.org'
  2 +
  3 +# Specify your gem's dependencies in vagrant-lxd.gemspec
  4 +#gemspec
  5 +
  6 +group :development do
  7 + gem "vagrant", git: "https://github.com/mitchellh/vagrant.git"
  8 +end
  9 +
  10 +group :plugins do
  11 + gem "vagrant-lxd", path: "."
  12 +end
  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 +
  1 +require "rubygems"
  2 +require "bundler/setup"
  3 +Bundler::GemHelper.install_tasks
  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
  1 +#!/usr/bin/env bash
  2 +set -euo pipefail
  3 +IFS=$'\n\t'
  4 +set -vx
  5 +
  6 +bundle install
  7 +
  8 +# Do any other automated setup that you need to do here
  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.
  1 +{
  2 + "provider": "lxd"
  3 +}
  1 +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
  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 +}
No preview for this file type
  1 +require 'bundler'
  2 +
  3 +begin
  4 + require 'vagrant'
  5 +rescue LoadError
  6 + Bundler.require(:default, :development)
  7 +end
  8 +
  9 +require 'vagrant/lxd/version'
  10 +require 'vagrant/lxd/plugin'
  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:
  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:
  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:
  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:
  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:
  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:
  1 +module Vagrant
  2 + module Lxd
  3 + class Command < Vagrant.plugin('2', :command)
  4 + # def initialize(argv, env)
  5 + # super argv, env
  6 + # end
  7 +
  8 + def execute
  9 + @env.ui.info("my own plugin", :prefix => false)
  10 + end
  11 + end
  12 + end
  13 +end
  14 +
  15 +# vim: set et ts=2 sw=2:
  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:
  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:
  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:
  1 +module Vagrant
  2 + module Lxd
  3 + VERSION = "0.0.1"
  4 + end
  5 +end
  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