Use Util::Tempfile when configuring networks

This fixes a fairly large tempfile leak. Vagrant uses a template
renderer to write network configuration files locally to disk. Then,
that temporarily file is uploaded to the remote host and moved into
place. Since Vagrant is such a short-lived process, GC never came along
and cleaned up those tempfiles, resulting in many temporary files being
created through regular Vagrant usage.

The Util::Tempfile class uses a block to ensure the temporary file is
deleted when the block finishes. This API required small tweaks to the
usage, but provides more safety to ensure the files are deleted.
This commit is contained in:
Seth Vargo 2016-05-28 23:17:40 -04:00
parent 3d2390fc94
commit 5a4f345363
No known key found for this signature in database
GPG Key ID: 905A90C2949E8787
22 changed files with 339 additions and 161 deletions

View File

@ -5,11 +5,14 @@ require "log4r"
require_relative "helper" require_relative "helper"
require_relative "shell" require_relative "shell"
require_relative "command_filter" require_relative "command_filter"
require_relative "../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module CommunicatorWinRM module CommunicatorWinRM
# Provides communication channel for Vagrant commands via WinRM. # Provides communication channel for Vagrant commands via WinRM.
class Communicator < Vagrant.plugin("2", :communicator) class Communicator < Vagrant.plugin("2", :communicator)
include Vagrant::Util
def self.match?(machine) def self.match?(machine)
# This is useless, and will likely be removed in the future (this # This is useless, and will likely be removed in the future (this
# whole method). # whole method).
@ -202,15 +205,11 @@ module VagrantPlugins
interactive: interactive, interactive: interactive,
}) })
guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1" guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1"
file = Tempfile.new(["vagrant-elevated-shell", "ps1"]) Tempfile.create(["vagrant-elevated-shell", "ps1"]) do |f|
begin f.write(script)
file.write(script) f.fsync
file.fsync f.close
file.close upload(f.path, guest_script_path)
upload(file.path, guest_script_path)
ensure
file.close
file.unlink
end end
# Convert to double byte unicode string then base64 encode # Convert to double byte unicode string then base64 encode

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestArch module GuestArch
@ -10,23 +9,29 @@ module VagrantPlugins
include Vagrant::Util include Vagrant::Util
def self.configure_networks(machine, networks) def self.configure_networks(machine, networks)
interfaces = Array.new tempfiles = []
interfaces = []
machine.communicate.sudo("ip -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'") do |_, result| machine.communicate.sudo("ip -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'") do |_, result|
interfaces = result.split("\n") interfaces = result.split("\n")
end end
networks.each do |network| networks.each.with_index do |network, i|
network[:device] = interfaces[network[:interface]] network[:device] = interfaces[network[:interface]]
entry = TemplateRenderer.render("guests/arch/network_#{network[:type]}", options: network) entry = TemplateRenderer.render("guests/arch/network_#{network[:type]}",
options: network)
temp = Tempfile.new("vagrant") remote_path = "/tmp/vagrant-network-#{Time.now.to_i}-#{i}"
temp.binmode
temp.write(entry)
temp.close
machine.communicate.upload(temp.path, "/tmp/vagrant_network") Tempfile.create("arch-configure-networks") do |f|
machine.communicate.sudo("mv /tmp/vagrant_network /etc/netctl/#{network[:device]}") f.write(entry)
f.fsync
f.close
machine.communicate.upload(f.path, remote_path)
end
machine.communicate.sudo("mv #{remote_path} /etc/netctl/#{network[:device]}")
machine.communicate.sudo("ip link set #{network[:device]} down && netctl restart #{network[:device]} && netctl enable #{network[:device]}") machine.communicate.sudo("ip link set #{network[:device]} down && netctl restart #{network[:device]} && netctl enable #{network[:device]}")
end end
end end

View File

@ -1,6 +1,5 @@
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestCoreOS module GuestCoreOS
@ -54,11 +53,11 @@ module VagrantPlugins
}) })
end end
Tempfile.open("vagrant") do |temp| Tempfile.create("coreos-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
comm.upload(temp.path, "/tmp/etcd-cluster.service") comm.upload(f.path, "/tmp/etcd-cluster.service")
end end
comm.sudo("mv /tmp/etcd-cluster.service /media/state/units/") comm.sudo("mv /tmp/etcd-cluster.service /media/state/units/")

View File

@ -1,7 +1,7 @@
require 'set' require "set"
require 'tempfile'
require "vagrant/util/template_renderer" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module GuestDebian module GuestDebian
@ -29,14 +29,14 @@ module VagrantPlugins
entries << entry entries << entry
end end
# Perform the careful dance necessary to reconfigure # Perform the careful dance necessary to reconfigure the network
# the network interfaces # interfaces.
temp = Tempfile.new("vagrant") Tempfile.create("debian-configure-networks") do |f|
temp.binmode f.write(entries.join("\n"))
temp.write(entries.join("\n")) f.fsync
temp.close f.close
comm.upload(f.path, "/tmp/vagrant-network-entry")
comm.upload(temp.path, "/tmp/vagrant-network-entry") end
# Bring down all the interfaces we're reconfiguring. By bringing down # Bring down all the interfaces we're reconfiguring. By bringing down
# each specifically, we avoid reconfiguring eth0 (the NAT interface) so # each specifically, we avoid reconfiguring eth0 (the NAT interface) so

View File

@ -1,8 +1,8 @@
require "set" require "set"
require "tempfile"
require "vagrant/util/retryable" require_relative "../../../../lib/vagrant/util/retryable"
require "vagrant/util/template_renderer" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module GuestFedora module GuestFedora
@ -96,12 +96,12 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/fedora/network_#{network[:type]}", entry = TemplateRenderer.render("guests/fedora/network_#{network[:type]}",
options: network) options: network)
temp = Tempfile.new("vagrant") Tempfile.create("fedora-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
machine.communicate.upload(f.path, "/tmp/vagrant-network-entry_#{interface}")
machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry_#{interface}") end
end end
# Bring down all the interfaces we're reconfiguring. By bringing down # Bring down all the interfaces we're reconfiguring. By bringing down

View File

@ -1,6 +1,5 @@
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestFreeBSD module GuestFreeBSD
@ -29,13 +28,13 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/freebsd/network_#{network[:type]}", entry = TemplateRenderer.render("guests/freebsd/network_#{network[:type]}",
options: network, ifname: ifname) options: network, ifname: ifname)
# Write the entry to a temporary location Tempfile.create("freebsd-configure-networks") do |f|
temp = Tempfile.new("vagrant") f.write(entry)
temp.binmode f.fsync
temp.write(entry) f.close
temp.close machine.communicate.upload(f.path, "/tmp/vagrant-network-entry")
end
machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry")
machine.communicate.sudo("su -m root -c 'cat /tmp/vagrant-network-entry >> /etc/rc.conf'", {shell: "sh"}) machine.communicate.sudo("su -m root -c 'cat /tmp/vagrant-network-entry >> /etc/rc.conf'", {shell: "sh"})
machine.communicate.sudo("rm -f /tmp/vagrant-network-entry", {shell: "sh"}) machine.communicate.sudo("rm -f /tmp/vagrant-network-entry", {shell: "sh"})

View File

@ -1,6 +1,5 @@
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestFuntoo module GuestFuntoo
@ -23,12 +22,15 @@ module VagrantPlugins
ifFile = "netif.eth#{network[:interface]}" ifFile = "netif.eth#{network[:interface]}"
entry = TemplateRenderer.render("guests/funtoo/network_#{network[:type]}", entry = TemplateRenderer.render("guests/funtoo/network_#{network[:type]}",
options: network) options: network)
# Upload the entry to a temporary location # Upload the entry to a temporary location
temp = Tempfile.new("vagrant") Tempfile.create("funtoo-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
comm.upload(temp.path, "/tmp/vagrant-#{ifFile}") comm.upload(f.path, "/tmp/vagrant-#{ifFile}")
end
comm.sudo("cp /tmp/vagrant-#{ifFile} /etc/conf.d/#{ifFile}") comm.sudo("cp /tmp/vagrant-#{ifFile} /etc/conf.d/#{ifFile}")
comm.sudo("chmod 0644 /etc/conf.d/#{ifFile}") comm.sudo("chmod 0644 /etc/conf.d/#{ifFile}")
comm.sudo("ln -fs /etc/init.d/netif.tmpl /etc/init.d/#{ifFile}") comm.sudo("ln -fs /etc/init.d/netif.tmpl /etc/init.d/#{ifFile}")

View File

@ -1,6 +1,5 @@
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestGentoo module GuestGentoo
@ -21,12 +20,12 @@ module VagrantPlugins
options: network) options: network)
# Upload the entry to a temporary location # Upload the entry to a temporary location
temp = Tempfile.new("vagrant") Tempfile.create("gentoo-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
comm.upload(f.path, "/tmp/vagrant-network-entry")
comm.upload(temp.path, "/tmp/vagrant-network-entry") end
# Configure the interface # Configure the interface
comm.sudo("ln -fs /etc/init.d/net.lo /etc/init.d/net.eth#{network[:interface]}") comm.sudo("ln -fs /etc/init.d/net.lo /etc/init.d/net.eth#{network[:interface]}")

View File

@ -1,6 +1,5 @@
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestNetBSD module GuestNetBSD
@ -20,13 +19,13 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/netbsd/network_#{network[:type]}", entry = TemplateRenderer.render("guests/netbsd/network_#{network[:type]}",
options: network) options: network)
temp = Tempfile.new("vagrant") Tempfile.create("netbsd-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
machine.communicate.upload(f.path, "/tmp/vagrant-network-entry")
end
# upload it and append it to the new rc.conf file
machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry")
machine.communicate.sudo("cat /tmp/vagrant-network-entry >> #{newrcconf}") machine.communicate.sudo("cat /tmp/vagrant-network-entry >> #{newrcconf}")
machine.communicate.sudo("rm -f /tmp/vagrant-network-entry") machine.communicate.sudo("rm -f /tmp/vagrant-network-entry")
@ -45,7 +44,6 @@ module VagrantPlugins
# install new rc.conf # install new rc.conf
machine.communicate.sudo("install -c -o 0 -g 0 -m 644 #{newrcconf} /etc/rc.conf") machine.communicate.sudo("install -c -o 0 -g 0 -m 644 #{newrcconf} /etc/rc.conf")
end end
end end
end end

View File

@ -1,6 +1,5 @@
require 'tempfile' require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestNixos module GuestNixos
@ -16,13 +15,15 @@ module VagrantPlugins
# Upload a file. # Upload a file.
def self.upload(machine, content, remote_path) def self.upload(machine, content, remote_path)
local_temp = Tempfile.new("vagrant-upload")
local_temp.binmode
local_temp.write(content)
local_temp.close
remote_temp = mktemp(machine) remote_temp = mktemp(machine)
machine.communicate.upload(local_temp.path, "#{remote_temp}")
local_temp.delete Tempfile.create("nixos-change-host-name") do |f|
f.write(content)
f.fsync
f.close
machine.communicate.upload(f.path, "#{remote_temp}")
end
machine.communicate.sudo("mv #{remote_temp} #{remote_path}") machine.communicate.sudo("mv #{remote_temp} #{remote_path}")
end end

View File

@ -1,7 +1,7 @@
require 'tempfile' require "ipaddr"
require 'ipaddr'
require "vagrant/util/template_renderer" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module GuestNixos module GuestNixos
@ -65,13 +65,15 @@ module VagrantPlugins
# Upload a file. # Upload a file.
def self.upload(machine, content, remote_path) def self.upload(machine, content, remote_path)
local_temp = Tempfile.new("vagrant-upload")
local_temp.binmode
local_temp.write(content)
local_temp.close
remote_temp = mktemp(machine) remote_temp = mktemp(machine)
machine.communicate.upload(local_temp.path, "#{remote_temp}")
local_temp.delete Tempfile.create("nixos-configure-networks") do |f|
f.write(content)
f.fsync
f.close
machine.communicate.upload(f.path, "#{remote_temp}")
end
machine.communicate.sudo("mv #{remote_temp} #{remote_path}") machine.communicate.sudo("mv #{remote_temp} #{remote_path}")
end end

View File

@ -1,6 +1,5 @@
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestOpenBSD module GuestOpenBSD
@ -13,10 +12,12 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/openbsd/network_#{network[:type]}", entry = TemplateRenderer.render("guests/openbsd/network_#{network[:type]}",
options: network) options: network)
temp = Tempfile.new("vagrant") Tempfile.create("openbsd-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
machine.communicate.upload(f.path, "/tmp/vagrant-network-entry")
end
# Determine the interface prefix... # Determine the interface prefix...
command = "ifconfig -a | grep -o ^[0-9a-z]*" command = "ifconfig -a | grep -o ^[0-9a-z]*"
@ -31,7 +32,6 @@ module VagrantPlugins
end end
end end
machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry")
machine.communicate.sudo("mv /tmp/vagrant-network-entry /etc/hostname.#{ifname}") machine.communicate.sudo("mv /tmp/vagrant-network-entry /etc/hostname.#{ifname}")
# remove old configurations # remove old configurations

View File

@ -1,8 +1,8 @@
require "set" require "set"
require "tempfile"
require "vagrant/util/retryable" require_relative "../../../../lib/vagrant/util/retryable"
require "vagrant/util/template_renderer" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module GuestRedHat module GuestRedHat
@ -55,12 +55,12 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/redhat/network_#{network[:type]}", entry = TemplateRenderer.render("guests/redhat/network_#{network[:type]}",
options: network) options: network)
temp = Tempfile.new("vagrant") Tempfile.create("red-hat-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
machine.communicate.upload(f.path, "/tmp/vagrant-network-entry_#{network[:interface]}")
machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry_#{network[:interface]}") end
end end
# Bring down all the interfaces we're reconfiguring. By bringing down # Bring down all the interfaces we're reconfiguring. By bringing down

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
require "tempfile" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
require "vagrant/util/template_renderer"
module VagrantPlugins module VagrantPlugins
module GuestSlackware module GuestSlackware
@ -20,12 +19,13 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/slackware/network_#{network[:type]}", options: network) entry = TemplateRenderer.render("guests/slackware/network_#{network[:type]}", options: network)
temp = Tempfile.new("vagrant") Tempfile.create("slackware-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
machine.communicate.upload(f.path, "/tmp/vagrant_network")
end
machine.communicate.upload(temp.path, "/tmp/vagrant_network")
machine.communicate.sudo("mv /tmp/vagrant_network /etc/rc.d/rc.inet1.conf") machine.communicate.sudo("mv /tmp/vagrant_network /etc/rc.d/rc.inet1.conf")
machine.communicate.sudo("/etc/rc.d/rc.inet1") machine.communicate.sudo("/etc/rc.d/rc.inet1")
end end

View File

@ -1,8 +1,8 @@
require "set" require "set"
require "tempfile"
require "vagrant/util/retryable" require_relative "../../../../lib/vagrant/util/retryable"
require "vagrant/util/template_renderer" require_relative "../../../../lib/vagrant/util/template_renderer"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module GuestSUSE module GuestSUSE
@ -33,12 +33,12 @@ module VagrantPlugins
entry = TemplateRenderer.render("guests/suse/network_#{network[:type]}", entry = TemplateRenderer.render("guests/suse/network_#{network[:type]}",
options: network) options: network)
temp = Tempfile.new("vagrant") Tempfile.create("suse-configure-networks") do |f|
temp.binmode f.write(entry)
temp.write(entry) f.fsync
temp.close f.close
machine.communicate.upload(f.path, "/tmp/vagrant-network-entry_#{network[:interface]}")
machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry_#{network[:interface]}") end
end end
# Bring down all the interfaces we're reconfiguring. By bringing down # Bring down all the interfaces we're reconfiguring. By bringing down

View File

@ -1,11 +1,11 @@
require 'tempfile'
require_relative "base" require_relative "base"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module Ansible module Ansible
module Provisioner module Provisioner
class Guest < Base class Guest < Base
include Vagrant::Util
def initialize(machine, config) def initialize(machine, config)
super super
@ -103,14 +103,14 @@ module VagrantPlugins
inventory_basedir = File.join(config.tmp_path, "inventory") inventory_basedir = File.join(config.tmp_path, "inventory")
inventory_path = File.join(inventory_basedir, "vagrant_ansible_local_inventory") inventory_path = File.join(inventory_basedir, "vagrant_ansible_local_inventory")
temp_inventory = Tempfile.new("vagrant_ansible_local_inventory_#{@machine.name}")
temp_inventory.write(inventory_content)
temp_inventory.close
create_and_chown_remote_folder(inventory_basedir) create_and_chown_remote_folder(inventory_basedir)
@machine.communicate.tap do |comm| @machine.communicate.sudo("rm -f #{inventory_path}", error_check: false)
comm.sudo("rm -f #{inventory_path}", error_check: false)
comm.upload(temp_inventory.path, inventory_path) Tempfile.create("ansible-local-inventory-#{@machine.name}") do |f|
f.write(inventory_content)
f.fsync
f.close
@machine.communicate.upload(f.path, inventory_path)
end end
return inventory_basedir return inventory_basedir

View File

@ -1,7 +1,7 @@
require "digest/md5" require "digest/md5"
require "tempfile"
require_relative "base" require_relative "base"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins module VagrantPlugins
module Chef module Chef
@ -54,17 +54,15 @@ module VagrantPlugins
# Write the raw recipe contents to a tempfile and upload that to the # Write the raw recipe contents to a tempfile and upload that to the
# machine. # machine.
def upload_recipe def upload_recipe
# Write the raw recipe contents to a tempfile # Write the raw recipe contents to a tempfile and upload
file = Tempfile.new(["vagrant-chef-apply", ".rb"]) Tempfile.create(["chef-apply", ".rb"]) do |f|
file.write(config.recipe) f.write(config.recipe)
file.rewind f.fsync
f.close
# Upload the tempfile to the guest # Upload the tempfile to the guest
@machine.communicate.upload(file.path, target_recipe_path) @machine.communicate.upload(f.path, target_recipe_path)
ensure end
# Delete our template
file.close
file.unlink
end end
end end
end end

View File

@ -0,0 +1,37 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestArch::Cap::ChangeHostName" do
let(:described_class) do
VagrantPlugins::GuestArch::Plugin
.components
.guest_capabilities[:arch]
.get(:change_host_name)
end
let(:machine) { double("machine") }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(communicator)
end
after do
communicator.verify_expectations!
end
describe ".change_host_name" do
let(:hostname) { "example.com" }
it "sets the hostname" do
communicator.stub_command("sudo hostname | grep '#{hostname}'", exit_code: 1)
communicator.expect_command("hostnamectl set-hostname #{hostname}")
described_class.change_host_name(machine, hostname)
end
it "does not change the hostname if already set" do
communicator.stub_command("sudo hostname | grep '#{hostname}'", exit_code: 0)
described_class.change_host_name(machine, hostname)
expect(communicator.received_commands.size).to eq(1)
end
end
end

View File

@ -0,0 +1,48 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestArch::Cap::ConfigureNetworks" do
let(:described_class) do
VagrantPlugins::GuestArch::Plugin
.components
.guest_capabilities[:arch]
.get(:configure_networks)
end
let(:machine) { double("machine") }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(communicator)
communicator.stub_command("ip -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'",
stdout: "eth1\neth2")
end
after do
communicator.verify_expectations!
end
describe ".configure_networks" do
let(:network_1) do
{
interface: 0,
type: "dhcp",
}
end
let(:network_2) do
{
interface: 1,
type: "static",
ip: "33.33.33.10",
netmask: "255.255.0.0",
gateway: "33.33.0.1",
}
end
it "creates and starts the networks" do
communicator.expect_command("ip link set eth1 down && netctl restart eth1 && netctl enable eth1")
communicator.expect_command("ip link set eth2 down && netctl restart eth2 && netctl enable eth2")
described_class.configure_networks(machine, [network_1, network_2])
end
end
end

View File

@ -0,0 +1,37 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestCoreOS::Cap::ChangeHostName" do
let(:described_class) do
VagrantPlugins::GuestCoreOS::Plugin
.components
.guest_capabilities[:coreos]
.get(:change_host_name)
end
let(:machine) { double("machine") }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(communicator)
end
after do
communicator.verify_expectations!
end
describe ".change_host_name" do
let(:hostname) { "example.com" }
it "sets the hostname" do
communicator.stub_command("sudo hostname --fqdn | grep '#{hostname}'", exit_code: 1)
communicator.expect_command("hostname example")
described_class.change_host_name(machine, hostname)
end
it "does not change the hostname if already set" do
communicator.stub_command("sudo hostname --fqdn | grep '#{hostname}'", exit_code: 0)
described_class.change_host_name(machine, hostname)
expect(communicator.received_commands.size).to eq(1)
end
end
end

View File

@ -1,10 +1,14 @@
require File.expand_path("../../../../../base", __FILE__) require_relative "../../../../base"
require File.expand_path("../../../support/shared/debian_like_host_name_examples", __FILE__) require_relative "../../support/shared/debian_like_host_name_examples"
describe "VagrantPlugins::GuestDebian::Cap::ChangeHostName" do describe "VagrantPlugins::GuestDebian::Cap::ChangeHostName" do
let(:described_class) do let(:described_class) do
VagrantPlugins::GuestDebian::Plugin.components.guest_capabilities[:debian].get(:change_host_name) VagrantPlugins::GuestDebian::Plugin
.components
.guest_capabilities[:debian]
.get(:change_host_name)
end end
let(:machine) { double("machine") } let(:machine) { double("machine") }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
let(:old_hostname) { 'oldhostname.olddomain.tld' } let(:old_hostname) { 'oldhostname.olddomain.tld' }

View File

@ -0,0 +1,50 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestDebian::Cap::ConfigureNetworks" do
let(:described_class) do
VagrantPlugins::GuestDebian::Plugin
.components
.guest_capabilities[:debian]
.get(:configure_networks)
end
let(:machine) { double("machine") }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(communicator)
end
after do
communicator.verify_expectations!
end
describe ".configure_networks" do
let(:network_0) do
{
interface: 0,
type: "dhcp",
}
end
let(:network_1) do
{
interface: 1,
type: "static",
ip: "33.33.33.10",
netmask: "255.255.0.0",
gateway: "33.33.0.1",
}
end
it "creates and starts the networks" do
communicator.expect_command("/sbin/ifdown eth0 2> /dev/null || true")
communicator.expect_command("/sbin/ip addr flush dev eth0 2> /dev/null")
communicator.expect_command("/sbin/ifdown eth1 2> /dev/null || true")
communicator.expect_command("/sbin/ip addr flush dev eth1 2> /dev/null")
communicator.expect_command("/sbin/ifup eth0")
communicator.expect_command("/sbin/ifup eth1")
described_class.configure_networks(machine, [network_0, network_1])
end
end
end