vagrant-alpine 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c2fc2915174a868f52ce574bb9af430ac32bdfc3
4
+ data.tar.gz: 0716848819f01d49981e4da58430d3d6a015bb94
5
+ SHA512:
6
+ metadata.gz: 4c5693032537c8775b1a0396e01cb26683f25aa992561f3d85c8a154f5f81cf56b25f7ef5d0e90d2817c75500800def2bc8a62f62c3043e213cd4ba697d1ac15
7
+ data.tar.gz: bfdd58c7edc571e0de7dd59bbad1fff77b7e0de3dad43e367f920cd71ebb593babda86cd4489a982242a89f5f091703bb9ff6aac53d967eb69ac5f1533ead7a3
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /vendor/
10
+ Vagrantfile
11
+ .vagrant
12
+ TODO.md
13
+
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --format doc
2
+ --order random
3
+ --color
4
+ --fail-fast
5
+
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ Metrics/LineLength:
2
+ Enabled: false
3
+ Documentation:
4
+ Enabled: false
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ vagrant-alpine
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.0
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ before_install:
3
+ - sudo apt-get update -qq
4
+ - sudo apt-get install -qq -y bsdtar
5
+ - rvm @global do gem uninstall bundler --all --executables
6
+ - gem uninstall bundler --all --executables
7
+ - gem install bundler --version '< 1.7.0'
8
+ rvm:
9
+ - 2.2.0
10
+ env:
11
+ global:
12
+ - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
13
+ script: rake
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git'
7
+ end
8
+
9
+ group :plugins do
10
+ gem 'vagrant-alpine', path: '.'
11
+ end
12
+
13
+ group :test do
14
+ gem 'rake'
15
+ gem 'rubocop'
16
+ end
17
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 matt maier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # [Vagrant Alpine Linux Guest](https://github.com/maier/vagrant-alpine)
2
+
3
+ This is a [Vagrant](http://vagrantup.com/) plugin adding support for [Alpine Linux](http://alpinelinx.org) guests.
4
+
5
+ > **NOTE:** The vagrant-alpine requires Vagrant 1.7+
6
+
7
+ ## Features
8
+
9
+ * Detection
10
+ * Set hostname
11
+ * Configure networking DHCP or static
12
+ * Halt/Shutdown the guest
13
+ * RSync detection and installation
14
+ * NFS client installation
15
+
16
+ ## Installation
17
+
18
+ ```
19
+ $ vagrant plugin install vagrant-alpine
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```
25
+ $ vagrant init maier/alpine-3.1.3
26
+ $ vagrant up
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ The vagrant-alpine plugin does not offer any configuration options.
32
+
33
+
34
+ ## Development
35
+
36
+ To work on the `vagrant-alpine` plugin, clone this repository, and use
37
+ [Bundler](http://gembundler.com) to get the dependencies:
38
+
39
+ ```
40
+ $ gem install bundler -v '~> 1.7.0'
41
+ $ bundle install --path vendor/bundle
42
+ ```
43
+
44
+ Once you have the dependencies, verify the unit tests pass with `rake`:
45
+
46
+ ```
47
+ $ bundle exec rake
48
+ ```
49
+
50
+ If those pass, you're ready to start developing. You can test
51
+ the plugin without installing it into your Vagrant environment
52
+ by creating a `Vagrantfile` in teh top level directory (it is gitignored).
53
+ There is an example supplied in this repository.
54
+ (`cp Vagrantfile.example Vagrantfile` and edit.)
55
+
56
+ Use bundler to execute Vagrant:
57
+ ```
58
+ $ bundle exec vagrant up
59
+ ```
60
+
61
+
62
+ ## Notes
63
+
64
+ Alpine Linux boxes for testing are available on
65
+ [Atlas](https://atlas.hashicorp.com/maier/). Packer templates
66
+ for building the boxes are in this
67
+ [GitHub repository](https://github.com/maier/packer-templates/).
68
+
69
+ Using `VAGRANT_LOG=info`, Vagrant's `--debug` switch, and `vb.gui = true`
70
+ were all very useful when originally developing this guest plugin.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ RSpec::Core::RakeTask.new
9
+ task :default => 'spec'
@@ -0,0 +1,49 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ #
5
+ # Vagrantfile for testing vagrant-alpine
6
+ #
7
+
8
+ Vagrant.configure(2) do |config|
9
+
10
+ config.vm.box = 'maier/alpine-3.1.3-x86_64'
11
+
12
+ # config.ssh.username = 'vagrant'
13
+ # config.ssh.password = 'vagrant'
14
+ # config.ssh.shell = '/bin/sh'
15
+
16
+ #
17
+ # Networking
18
+ #
19
+ # DHCP
20
+ # config.vm.network 'private_network', type: 'dhcp'
21
+ #
22
+ # Static (replace <IP> with an appropriate private address)
23
+ # config.vm.network 'private_network', ip: '<IP>', auto_config: true
24
+
25
+ #
26
+ # Shared folders
27
+ #
28
+ # Note, for shared folders via NFS a static IP *must* be provided
29
+ # until guest additions can be built and installed out of main.
30
+ # The reason being that although a DHCP interface does successfully
31
+ # get an IP, virtualbox is unaware of it and therefore cannot
32
+ # provide it to Vagrant.
33
+ #
34
+ # If not assigning a static IP, ensure the default
35
+ # share is disabled.
36
+ config.vm.synced_folder '.', '/vagrant', disabled: true
37
+ #
38
+ # Define NFS shares (comment out above when enabling
39
+ # this 'default' folder, or mount a different folder.)
40
+ # config.vm.synced_folder '.', '/vagrant', type: 'nfs'
41
+
42
+ config.vm.provider 'virtualbox' do |vb|
43
+ vb.name = 'vagrant-alpine-test'
44
+ vb.cpus = 1
45
+ vb.memory = 1024
46
+ # vb.gui = true
47
+ end
48
+
49
+ end
@@ -0,0 +1,23 @@
1
+ # rubocop:disable Style/FileName
2
+ #
3
+ # squelch:
4
+ # lib/vagrant-alpine.rb:1:1: C: Use snake_case for source file names.
5
+ # require 'pathname'
6
+ #
7
+ require 'pathname'
8
+ require 'vagrant-alpine/plugin'
9
+
10
+ module VagrantPlugins
11
+ module GuestAlpine
12
+ # lib_path = Pathname.new(File.expand_path('../vagrant-alpine', __FILE__))
13
+ # autoload :Action, lib_path.join('action')
14
+ # autoload :Errors, lib_path.join('errors')
15
+
16
+ # This returns the path to the source of this plugin.
17
+ #
18
+ # @return [Pathname]
19
+ def self.source_root
20
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,95 @@
1
+ module VagrantPlugins
2
+ module GuestAlpine
3
+ module Cap
4
+ class ChangeHostName
5
+ def self.change_host_name(machine, name)
6
+ new(machine, name).change!
7
+ end
8
+
9
+ attr_reader :machine, :new_hostname
10
+
11
+ def initialize(machine, new_hostname)
12
+ @machine = machine
13
+ @new_hostname = new_hostname
14
+ end
15
+
16
+ def change!
17
+ return unless should_change?
18
+
19
+ update_etc_hostname
20
+ update_etc_hosts
21
+ refresh_hostname_service
22
+ update_mailname
23
+ renew_dhcp
24
+ end
25
+
26
+ def should_change?
27
+ new_hostname != current_hostname
28
+ end
29
+
30
+ def current_hostname
31
+ @current_hostname ||= fetch_current_hostname
32
+ end
33
+
34
+ def fetch_current_hostname
35
+ hostname = ''
36
+ sudo 'hostname -f' do |type, data|
37
+ hostname = data.chomp if type == :stdout && hostname.empty?
38
+ end
39
+
40
+ hostname
41
+ end
42
+
43
+ def update_etc_hostname
44
+ sudo("echo '#{short_hostname}' > /etc/hostname")
45
+ end
46
+
47
+ # /etc/hosts should resemble:
48
+ # 127.0.0.1 localhost
49
+ # 127.0.1.1 host.fqdn.com host.fqdn host
50
+ def update_etc_hosts
51
+ if test("grep '#{current_hostname}' /etc/hosts")
52
+ # Current hostname entry is in /etc/hosts
53
+ ip_address = '([0-9]{1,3}\.){3}[0-9]{1,3}'
54
+ search = "^(#{ip_address})\\s+#{Regexp.escape(current_hostname)}(\\s.*)?$"
55
+ replace = "\\1 #{fqdn} #{short_hostname}"
56
+ expression = ['s', search, replace, 'g'].join('@')
57
+
58
+ sudo("sed -ri '#{expression}' /etc/hosts")
59
+ else
60
+ # Current hostname entry isn't in /etc/hosts, just append it
61
+ sudo("echo '127.0.1.1 #{fqdn} #{short_hostname}' >>/etc/hosts")
62
+ end
63
+ end
64
+
65
+ def refresh_hostname_service
66
+ sudo('hostname -F /etc/hostname')
67
+ end
68
+
69
+ def update_mailname
70
+ sudo('hostname --fqdn > /etc/mailname')
71
+ end
72
+
73
+ def renew_dhcp
74
+ sudo('ifdown -a; ifup -a; ifup eth0')
75
+ end
76
+
77
+ def fqdn
78
+ new_hostname
79
+ end
80
+
81
+ def short_hostname
82
+ new_hostname.split('.').first
83
+ end
84
+
85
+ def sudo(cmd, &block)
86
+ machine.communicate.sudo(cmd, &block)
87
+ end
88
+
89
+ def test(cmd)
90
+ machine.communicate.test(cmd)
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,64 @@
1
+ # rubocop:disable Metrics/MethodLength
2
+ # rubocop:disable Metrics/AbcSize
3
+ # rubocop:disable Style/BracesAroundHashParameters
4
+ #
5
+ # FIXME: address disabled warnings
6
+ #
7
+ require 'set'
8
+ require 'tempfile'
9
+
10
+ require 'vagrant/util/template_renderer'
11
+
12
+ module VagrantPlugins
13
+ module GuestAlpine
14
+ module Cap
15
+ class ConfigureNetworks
16
+ include Vagrant::Util
17
+ def self.configure_networks(machine, networks)
18
+ machine.communicate.tap do |comm|
19
+ # First, remove any previous network modifications
20
+ # from the interface file.
21
+ comm.sudo("sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre")
22
+ comm.sudo("sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tail -n +2 > /tmp/vagrant-network-interfaces.post")
23
+
24
+ # Accumulate the configurations to add to the interfaces file as
25
+ # well as what interfaces we're actually configuring since we use that
26
+ # later.
27
+ interfaces = Set.new
28
+ entries = []
29
+ networks.each do |network|
30
+ interfaces.add(network[:interface])
31
+ entry = TemplateRenderer.render("guests/alpine/network_#{network[:type]}", { options: network, template_root: GuestAlpine.source_root.join('templates') })
32
+ entries << entry
33
+ end
34
+
35
+ # Perform the careful dance necessary to reconfigure
36
+ # the network interfaces
37
+ temp = Tempfile.new('vagrant')
38
+ temp.binmode
39
+ temp.write(entries.join("\n"))
40
+ temp.close
41
+
42
+ comm.upload(temp.path, '/tmp/vagrant-network-entry')
43
+
44
+ # Bring down all the interfaces we're reconfiguring. By bringing down
45
+ # each specifically, we avoid reconfiguring eth0 (the NAT interface) so
46
+ # SSH never dies.
47
+ interfaces.each do |interface|
48
+ comm.sudo("/sbin/ifdown eth#{interface} 2> /dev/null")
49
+ comm.sudo("/sbin/ip addr flush dev eth#{interface} 2> /dev/null")
50
+ end
51
+
52
+ comm.sudo('cat /tmp/vagrant-network-interfaces.pre /tmp/vagrant-network-entry /tmp/vagrant-network-interfaces.post > /etc/network/interfaces')
53
+ comm.sudo('rm -f /tmp/vagrant-network-interfaces.pre /tmp/vagrant-network-entry /tmp/vagrant-network-interfaces.post')
54
+
55
+ # Bring back up each network interface, reconfigured
56
+ interfaces.each do |interface|
57
+ comm.sudo("/sbin/ifup eth#{interface}")
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,21 @@
1
+ # rubocop:disable Style/RedundantBegin
2
+ # rubocop:disable Lint/HandleExceptions
3
+ #
4
+ # FIXME: address disabled warnings
5
+ #
6
+ module VagrantPlugins
7
+ module GuestAlpine
8
+ module Cap
9
+ class Halt
10
+ def self.halt(machine)
11
+ begin
12
+ machine.communicate.sudo('poweroff')
13
+ rescue Net::SSH::Disconnect, IOError
14
+ # Ignore, this probably means connection closed because it
15
+ # shut down and SSHd was stopped.
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module VagrantPlugins
2
+ module GuestAlpine
3
+ module Cap
4
+ class NFSClient
5
+ def self.nfs_client_install(machine)
6
+ machine.communicate.tap do |comm|
7
+ comm.sudo('apk add nfs-utils')
8
+ comm.sudo('rc-update add rpc.statd')
9
+ comm.sudo('rc-service rpc.statd start')
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module VagrantPlugins
2
+ module GuestAlpine
3
+ module Cap
4
+ class RSync
5
+ def self.rsync_installed(machine)
6
+ machine.communicate.test('test -f /usr/bin/rsync')
7
+ end
8
+
9
+ def self.rsync_install(machine)
10
+ machine.communicate.tap do |comm|
11
+ comm.sudo('apk add rsync')
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'vagrant'
3
+ rescue LoadError
4
+ raise 'The Vagrant Alpine Linux Guest plugin must be run within Vagrant.'
5
+ end
6
+
7
+ if Vagrant::VERSION < '1.7.0'
8
+ fail 'The vagrant-alpine plugin is only compatible with Vagrant 1.7+'
9
+ end
10
+
11
+ module VagrantPlugins
12
+ module GuestAlpine
13
+ class Guest < Vagrant.plugin('2', :guest)
14
+ def detect?(machine)
15
+ machine.communicate.test('cat /etc/alpine-release')
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,53 @@
1
+ begin
2
+ require 'vagrant'
3
+ rescue LoadError
4
+ raise 'The Vagrant Alpine Linux Guest plugin must be run within Vagrant.'
5
+ end
6
+
7
+ if Vagrant::VERSION < '1.7.0'
8
+ fail 'The vagrant-alpine plugin is only compatible with Vagrant 1.7+'
9
+ end
10
+
11
+ module VagrantPlugins
12
+ module GuestAlpine
13
+ class Plugin < Vagrant.plugin('2')
14
+ name 'Alpine guest'
15
+ description 'Alpine Linux guest support.'
16
+
17
+ guest('alpine', 'linux') do
18
+ require File.expand_path('../guest', __FILE__)
19
+ Guest
20
+ end
21
+
22
+ guest_capability('alpine', 'configure_networks') do
23
+ require_relative 'cap/configure_networks'
24
+ Cap::ConfigureNetworks
25
+ end
26
+
27
+ guest_capability('alpine', 'halt') do
28
+ require_relative 'cap/halt'
29
+ Cap::Halt
30
+ end
31
+
32
+ guest_capability('alpine', 'change_host_name') do
33
+ require_relative 'cap/change_host_name'
34
+ Cap::ChangeHostName
35
+ end
36
+
37
+ guest_capability('alpine', 'nfs_client_install') do
38
+ require_relative 'cap/nfs_client'
39
+ Cap::NFSClient
40
+ end
41
+
42
+ guest_capability('alpine', 'rsync_installed') do
43
+ require_relative 'cap/rsync'
44
+ Cap::RSync
45
+ end
46
+
47
+ guest_capability('alpine', 'rsync_install') do
48
+ require_relative 'cap/rsync'
49
+ Cap::RSync
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,6 @@
1
+ module VagrantPlugins
2
+ # Alpine Linux guest gem + plugin version
3
+ module GuestAlpine
4
+ VERSION = '0.1.1'
5
+ end
6
+ end
@@ -0,0 +1,128 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'VagrantPlugins::GuestAlpine::Cap::ChangeHostname' do
5
+ let(:described_class) do
6
+ VagrantPlugins::GuestAlpine::Plugin.components.guest_capabilities[:alpine].get(:change_host_name)
7
+ end
8
+ let(:machine) { double('machine') }
9
+ let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
10
+ let(:old_hostname) { 'oldhostname.olddomain.tld' }
11
+
12
+ before do
13
+ allow(machine).to receive(:communicate).and_return(communicator)
14
+ communicator.stub_command('hostname -f', stdout: old_hostname)
15
+ end
16
+
17
+ after do
18
+ communicator.verify_expectations!
19
+ end
20
+
21
+ describe '.change_host_name' do
22
+ it 'updates /etc/hostname on the machine' do
23
+ communicator.expect_command("echo 'newhostname' > /etc/hostname")
24
+ described_class.change_host_name(machine, 'newhostname.newdomain.tld')
25
+ end
26
+
27
+ it 'does nothing when the provided hostname is not different' do
28
+ described_class.change_host_name(machine, 'oldhostname.olddomain.tld')
29
+ expect(communicator.received_commands).to eq(['hostname -f'])
30
+ end
31
+
32
+ it 'refreshes the hostname service with the hostname command' do
33
+ communicator.expect_command('hostname -F /etc/hostname')
34
+ described_class.change_host_name(machine, 'newhostname.newdomain.tld')
35
+ end
36
+
37
+ it 'renews dhcp on the system with the new hostname' do
38
+ communicator.expect_command('ifdown -a; ifup -a; ifup eth0')
39
+ described_class.change_host_name(machine, 'newhostname.newdomain.tld')
40
+ end
41
+
42
+ describe 'flipping out the old hostname in /etc/hosts' do
43
+ let(:sed_command) do
44
+ # Here we run the change_host_name through and extract the recorded sed
45
+ # command from the dummy communicator
46
+ described_class.change_host_name(machine, 'newhostname.newdomain.tld')
47
+ communicator.received_commands.find { |cmd| cmd =~ /^sed/ }
48
+ end
49
+
50
+ # Now we extract the regexp from that sed command so we can do some
51
+ # verification on it
52
+ let(:expression) { sed_command.sub(%r{^sed -ri '\(.*\)' /etc/hosts$}, "\1") }
53
+ let(:search) { Regexp.new(expression.split('@')[1], Regexp::EXTENDED) }
54
+ let(:replace) { expression.split('@')[2] }
55
+
56
+ let(:grep_command) { "grep '#{old_hostname}' /etc/hosts" }
57
+
58
+ before do
59
+ communicator.stub_command(grep_command, exit_code: 0)
60
+ end
61
+
62
+ it 'works on an simple /etc/hosts file' do
63
+ original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
64
+ 127.0.0.1 localhost
65
+ 127.0.1.1 oldhostname.olddomain.tld oldhostname
66
+ ETC_HOSTS
67
+
68
+ modified_etc_hosts = original_etc_hosts.gsub(search, replace)
69
+
70
+ expect(modified_etc_hosts).to eq <<-RESULT.gsub(/^ */, '')
71
+ 127.0.0.1 localhost
72
+ 127.0.1.1 newhostname.newdomain.tld newhostname
73
+ RESULT
74
+ end
75
+
76
+ it 'does not modify lines which contain similar hostnames' do
77
+ original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
78
+ 127.0.0.1 localhost
79
+ 127.0.1.1 oldhostname.olddomain.tld oldhostname
80
+ # common prefix, but different fqdn
81
+ 192.168.12.34 oldhostname.olddomain.tld.different
82
+ # different characters at the dot
83
+ 192.168.34.56 oldhostname-olddomain.tld
84
+ ETC_HOSTS
85
+
86
+ modified_etc_hosts = original_etc_hosts.gsub(search, replace)
87
+
88
+ expect(modified_etc_hosts).to eq <<-RESULT.gsub(/^ */, '')
89
+ 127.0.0.1 localhost
90
+ 127.0.1.1 newhostname.newdomain.tld newhostname
91
+ # common prefix, but different fqdn
92
+ 192.168.12.34 oldhostname.olddomain.tld.different
93
+ # different characters at the dot
94
+ 192.168.34.56 oldhostname-olddomain.tld
95
+ RESULT
96
+ end
97
+
98
+ it "appends 127.0.1.1 if it isn't there" do
99
+ communicator.stub_command(grep_command, exit_code: 1)
100
+ described_class.change_host_name(machine, 'newhostname.newdomain.tld')
101
+
102
+ sed = communicator.received_commands.find { |cmd| cmd =~ /^sed/ }
103
+ expect(sed).to be_nil
104
+
105
+ echo = communicator.received_commands.find { |cmd| cmd =~ /^echo/ }
106
+ expect(echo).to_not be_nil
107
+ end
108
+
109
+ context 'when the old fqdn has a trailing dot' do
110
+ let(:old_hostname) { 'oldhostname.withtrailing.dot.' }
111
+
112
+ it 'modifies /etc/hosts properly' do
113
+ original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
114
+ 127.0.0.1 localhost
115
+ 127.0.1.1 oldhostname.withtrailing.dot. oldhostname
116
+ ETC_HOSTS
117
+
118
+ modified_etc_hosts = original_etc_hosts.gsub(search, replace)
119
+
120
+ expect(modified_etc_hosts).to eq <<-RESULT.gsub(/^ */, '')
121
+ 127.0.0.1 localhost
122
+ 127.0.1.1 newhostname.newdomain.tld newhostname
123
+ RESULT
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,40 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'VagrantPlugins::GuestAlpine::Cap::ConfigureNetworks' do
5
+ let(:described_class) do
6
+ VagrantPlugins::GuestAlpine::Plugin.components.guest_capabilities[:alpine].get(:configure_networks)
7
+ end
8
+ let(:machine) { double('machine') }
9
+ let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
10
+
11
+ before do
12
+ allow(machine).to receive(:communicate).and_return(communicator)
13
+ end
14
+
15
+ after do
16
+ communicator.verify_expectations!
17
+ end
18
+
19
+ it 'should configure networks' do
20
+ networks = [
21
+ { type: :static, ip: '192.168.10.10', netmask: '255.255.255.0', interface: 0, name: 'eth0' },
22
+ { type: :dhcp, interface: 1, name: 'eth1' }
23
+ ]
24
+
25
+ communicator.should_receive(:sudo).with("sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre")
26
+ communicator.should_receive(:sudo).with("sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tail -n +2 > /tmp/vagrant-network-interfaces.post")
27
+ communicator.should_receive(:sudo).with('/sbin/ifdown eth0 2> /dev/null')
28
+ communicator.should_receive(:sudo).with('/sbin/ip addr flush dev eth0 2> /dev/null')
29
+ communicator.should_receive(:sudo).with('/sbin/ifdown eth1 2> /dev/null')
30
+ communicator.should_receive(:sudo).with('/sbin/ip addr flush dev eth1 2> /dev/null')
31
+ communicator.should_receive(:sudo).with('cat /tmp/vagrant-network-interfaces.pre /tmp/vagrant-network-entry /tmp/vagrant-network-interfaces.post > /etc/network/interfaces')
32
+ communicator.should_receive(:sudo).with('rm -f /tmp/vagrant-network-interfaces.pre /tmp/vagrant-network-entry /tmp/vagrant-network-interfaces.post')
33
+ communicator.should_receive(:sudo).with('/sbin/ifup eth0')
34
+ communicator.should_receive(:sudo).with('/sbin/ifup eth1')
35
+
36
+ allow_message_expectations_on_nil
37
+
38
+ described_class.configure_networks(machine, networks)
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'VagrantPlugins::GuestAlpine::Cap::Halt' do
5
+ let(:described_class) do
6
+ VagrantPlugins::GuestAlpine::Plugin.components.guest_capabilities[:alpine].get(:halt)
7
+ end
8
+ let(:machine) { double('machine') }
9
+ let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
10
+
11
+ before do
12
+ allow(machine).to receive(:communicate).and_return(communicator)
13
+ end
14
+
15
+ after do
16
+ communicator.verify_expectations!
17
+ end
18
+
19
+ it 'should halt guest' do
20
+ communicator.should_receive(:sudo).with('poweroff')
21
+ allow_message_expectations_on_nil
22
+ described_class.halt(machine)
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'VagrantPlugins::GuestAlpine::Cap::NFSClient' do
5
+ let(:described_class) do
6
+ VagrantPlugins::GuestAlpine::Plugin.components.guest_capabilities[:alpine].get(:nfs_client_install)
7
+ end
8
+ let(:machine) { double('machine') }
9
+ let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
10
+
11
+ before do
12
+ allow(machine).to receive(:communicate).and_return(communicator)
13
+ end
14
+
15
+ after do
16
+ communicator.verify_expectations!
17
+ end
18
+
19
+ it 'should install nfs client' do
20
+ communicator.should_receive(:sudo).with('apk add nfs-utils')
21
+ communicator.should_receive(:sudo).with('rc-update add rpc.statd')
22
+ communicator.should_receive(:sudo).with('rc-service rpc.statd start')
23
+
24
+ allow_message_expectations_on_nil
25
+ described_class.nfs_client_install(machine)
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'VagrantPlugins::GuestAlpine::Cap::RSync' do
5
+ let(:machine) { double('machine') }
6
+ let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
7
+
8
+ before do
9
+ allow(machine).to receive(:communicate).and_return(communicator)
10
+ end
11
+
12
+ after do
13
+ communicator.verify_expectations!
14
+ end
15
+
16
+ let(:described_class) do
17
+ VagrantPlugins::GuestAlpine::Plugin.components.guest_capabilities[:alpine].get(:rsync_install)
18
+ end
19
+
20
+ it 'should install rsync' do
21
+ communicator.should_receive(:sudo).with('apk add rsync')
22
+ allow_message_expectations_on_nil
23
+ described_class.rsync_install(machine)
24
+ end
25
+
26
+ let(:described_class) do
27
+ VagrantPlugins::GuestAlpine::Plugin.components.guest_capabilities[:alpine].get(:rsync_installed)
28
+ end
29
+
30
+ it 'should verify rsync installed' do
31
+ communicator.should_receive(:test).with('test -f /usr/bin/rsync')
32
+ allow_message_expectations_on_nil
33
+ described_class.rsync_installed(machine)
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require 'vagrant-alpine/guest'
2
+
3
+ require 'vagrant-alpine/plugin'
4
+
5
+ require 'vagrant-alpine/cap/change_host_name'
6
+ require 'vagrant-alpine/cap/configure_networks'
7
+ require 'vagrant-alpine/cap/halt'
8
+ require 'vagrant-alpine/cap/rsync'
9
+ require 'vagrant-alpine/cap/nfs_client'
10
+
11
+ describe VagrantPlugins::GuestAlpine::Plugin do
12
+ it 'should be loaded with alpine' do
13
+ expect(described_class.components.guests[:alpine].first).to eq(VagrantPlugins::GuestAlpine::Guest)
14
+ end
15
+
16
+ {
17
+ change_host_name: VagrantPlugins::GuestAlpine::Cap::ChangeHostName,
18
+ configure_networks: VagrantPlugins::GuestAlpine::Cap::ConfigureNetworks,
19
+ halt: VagrantPlugins::GuestAlpine::Cap::Halt,
20
+ rsync_installed: VagrantPlugins::GuestAlpine::Cap::RSync,
21
+ rsync_install: VagrantPlugins::GuestAlpine::Cap::RSync,
22
+ nfs_client_install: VagrantPlugins::GuestAlpine::Cap::NFSClient
23
+ }.each do |cap, cls|
24
+ it "should be capable of #{cap} with alpine" do
25
+ expect(described_class.components.guest_capabilities[:alpine][cap])
26
+ .to eq(cls)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ require 'vagrant'
2
+ require 'support/dummy_communicator'
3
+
@@ -0,0 +1,84 @@
1
+ module VagrantTests
2
+ module DummyCommunicator
3
+ class Communicator < Vagrant.plugin("2", :communicator)
4
+ def ready?
5
+ true
6
+ end
7
+
8
+ attr_reader :known_commands
9
+
10
+ def initialize(machine)
11
+ @known_commands = Hash.new do |hash, key|
12
+ hash[key] = { expected: 0, received: 0, response: nil }
13
+ end
14
+ end
15
+
16
+ def expected_commands
17
+ known_commands.select do |command, info|
18
+ info[:expected] > 0
19
+ end
20
+ end
21
+
22
+ def received_commands
23
+ known_commands.select do |command, info|
24
+ info[:received] > 0
25
+ end.keys
26
+ end
27
+
28
+ def stub_command(command, response)
29
+ known_commands[command][:response] = response
30
+ end
31
+
32
+ def expect_command(command)
33
+ known_commands[command][:expected] += 1
34
+ end
35
+
36
+ def received_summary
37
+ received_commands.map { |cmd| " - #{cmd}" }.unshift('received:').join("\n")
38
+ end
39
+
40
+ def verify_expectations!
41
+ expected_commands.each do |command, info|
42
+ if info[:expected] != info[:received]
43
+ fail([
44
+ "expected to receive '#{command}' #{info[:expected]} times",
45
+ "got #{info[:received]} times instead",
46
+ received_summary
47
+ ].join("\n"))
48
+ end
49
+ end
50
+ end
51
+
52
+ def execute(command, opts=nil)
53
+ known = known_commands[command]
54
+ known[:received] += 1
55
+ response = known[:response]
56
+ return unless response
57
+
58
+ if block_given?
59
+ [:stdout, :stderr].each do |type|
60
+ Array(response[type]).each do |line|
61
+ yield type, line
62
+ end
63
+ end
64
+ end
65
+
66
+ if response[:raise]
67
+ raise response[:raise]
68
+ end
69
+
70
+ response[:exit_code]
71
+ end
72
+
73
+ def sudo(command, opts=nil, &block)
74
+ execute(command, opts, &block)
75
+ end
76
+
77
+ def test(command, opts=nil)
78
+ execute(command, opts) == 0
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+
@@ -0,0 +1,13 @@
1
+ #VAGRANT-BEGIN
2
+ # The contents below are automatically generated by Vagrant. Do not modify.
3
+ auto eth<%= options[:interface] %>
4
+ iface eth<%= options[:interface] %> inet dhcp
5
+ <% if !options[:use_dhcp_assigned_default_route] %>
6
+ post-up route del default dev $IFACE || true
7
+ <% else %>
8
+ # We need to disable eth0, see GH-2648
9
+ post-up route del default dev eth0
10
+ post-up dhclient $IFACE
11
+ pre-down route add default dev eth0
12
+ <% end %>
13
+ #VAGRANT-END
@@ -0,0 +1,7 @@
1
+ #VAGRANT-BEGIN
2
+ # The contents below are automatically generated by Vagrant. Do not modify.
3
+ auto eth<%= options[:interface] %>
4
+ iface eth<%= options[:interface] %> inet static
5
+ address <%= options[:ip] %>
6
+ netmask <%= options[:netmask] %>
7
+ #VAGRANT-END
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-alpine/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'vagrant-alpine'
8
+ spec.version = VagrantPlugins::GuestAlpine::VERSION
9
+ spec.license = 'MIT'
10
+
11
+ spec.authors = ['matt maier']
12
+ spec.email = ['maier@users.noreply.github.com']
13
+
14
+ spec.summary = 'Enables Vagrant to manage Alpine Linux Guests.'
15
+ spec.description = 'Enables Vagrant to manage Alpine Linux Guests.'
16
+ spec.homepage = 'https://github.com/maier/vagrant-alpine'
17
+
18
+ spec.add_development_dependency 'rake', '~> 10.4.2'
19
+ spec.add_development_dependency 'rspec-core', '~> 2.14'
20
+ spec.add_development_dependency 'rspec-expectations', '~> 2.14'
21
+ spec.add_development_dependency 'rspec-mocks', '~> 2.14'
22
+
23
+ spec.files = `git ls-files -z`.split("\x0")
24
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
+ spec.require_path = 'lib'
26
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-alpine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - matt maier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 10.4.2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 10.4.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-expectations
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-mocks
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.14'
69
+ description: Enables Vagrant to manage Alpine Linux Guests.
70
+ email:
71
+ - maier@users.noreply.github.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".rubocop.yml"
79
+ - ".ruby-gemset"
80
+ - ".ruby-version"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - LICENSE
84
+ - README.md
85
+ - Rakefile
86
+ - Vagrantfile.example
87
+ - lib/vagrant-alpine.rb
88
+ - lib/vagrant-alpine/cap/change_host_name.rb
89
+ - lib/vagrant-alpine/cap/configure_networks.rb
90
+ - lib/vagrant-alpine/cap/halt.rb
91
+ - lib/vagrant-alpine/cap/nfs_client.rb
92
+ - lib/vagrant-alpine/cap/rsync.rb
93
+ - lib/vagrant-alpine/guest.rb
94
+ - lib/vagrant-alpine/plugin.rb
95
+ - lib/vagrant-alpine/version.rb
96
+ - spec/cap/change_host_name_spec.rb
97
+ - spec/cap/configure_networks_spec.rb
98
+ - spec/cap/halt_spec.rb
99
+ - spec/cap/nfs_client_spec.rb
100
+ - spec/cap/rsync_spec.rb
101
+ - spec/guest_spec.rb
102
+ - spec/spec_helper.rb
103
+ - spec/support/dummy_communicator.rb
104
+ - templates/guests/alpine/network_dhcp.erb
105
+ - templates/guests/alpine/network_static.erb
106
+ - vagrant-alpine.gemspec
107
+ homepage: https://github.com/maier/vagrant-alpine
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.4.6
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Enables Vagrant to manage Alpine Linux Guests.
131
+ test_files: []