From 0c5d55e69cc739c6f4c9bd5c1332645ec74e1066 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 16 Oct 2018 11:54:58 -0700 Subject: [PATCH] Fixes #9763, #10300: Split out how hostname is set with Debian hosts Prior to this commit, the hostname was set with one big bash script and attempted to determine what tools are available. This commit changes that by splitting out that tool check on the Vagrant side of things with the GuestInspection class, and adds back restarting networking to get a DHCP lease with the change rather than using `dhclient`. This pattern matches how hostnames are set in the redhat capability. --- plugins/guests/debian/cap/change_host_name.rb | 33 ++++++--- .../debian/cap/change_host_name_test.rb | 73 ++++++++++++++++++- 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/plugins/guests/debian/cap/change_host_name.rb b/plugins/guests/debian/cap/change_host_name.rb index 6cba5f34c..d8a127100 100644 --- a/plugins/guests/debian/cap/change_host_name.rb +++ b/plugins/guests/debian/cap/change_host_name.rb @@ -2,6 +2,9 @@ module VagrantPlugins module GuestDebian module Cap class ChangeHostName + + extend Vagrant::Util::GuestInspection::Linux + def self.change_host_name(machine, name) comm = machine.communicate @@ -10,11 +13,6 @@ module VagrantPlugins comm.sudo <<-EOH.gsub(/^ {14}/, '') # Set the hostname echo '#{basename}' > /etc/hostname - hostname -F /etc/hostname - - if command -v hostnamectl; then - hostnamectl set-hostname '#{basename}' - fi # Prepend ourselves to /etc/hosts grep -w '#{name}' /etc/hosts || { @@ -28,6 +26,13 @@ module VagrantPlugins # Update mailname echo '#{name}' > /etc/mailname + EOH + + if hostnamectl?(comm) + comm.sudo("hostnamectl set-hostname '#{basename}'") + else + comm.sudo <<-EOH.gsub(/^ {14}/, '') + hostname -F /etc/hostname # Restart hostname services if test -f /etc/init.d/hostname; then /etc/init.d/hostname start || true @@ -36,11 +41,19 @@ module VagrantPlugins if test -f /etc/init.d/hostname.sh; then /etc/init.d/hostname.sh start || true fi - if test -x /sbin/dhclient ; then - /sbin/dhclient -r - /sbin/dhclient -nw - fi - EOH + EOH + end + + restart_command = "/etc/init.d/networking restart" + + if systemd?(comm) + if systemd_networkd?(comm) + restart_command = "systemctl restart systemd-networkd.service" + elsif systemd_controlled?(comm, "NetworkManager.service") + restart_command = "systemctl restart NetworkManager.service" + end + end + comm.sudo(restart_command) end end end diff --git a/test/unit/plugins/guests/debian/cap/change_host_name_test.rb b/test/unit/plugins/guests/debian/cap/change_host_name_test.rb index dee94a67c..73a70564c 100644 --- a/test/unit/plugins/guests/debian/cap/change_host_name_test.rb +++ b/test/unit/plugins/guests/debian/cap/change_host_name_test.rb @@ -20,14 +20,81 @@ describe "VagrantPlugins::GuestDebian::Cap::ChangeHostName" do describe ".change_host_name" do let(:cap) { caps.get(:change_host_name) } - let(:name) { 'banana-rama.example.com' } + let(:systemd) { true } + let(:hostnamectl) { true } + let(:networkd) { true } + let(:network_manager) { false } + + before do + allow(cap).to receive(:systemd?).and_return(systemd) + allow(cap).to receive(:hostnamectl?).and_return(hostnamectl) + allow(cap).to receive(:systemd_networkd?).and_return(networkd) + allow(cap).to receive(:systemd_controlled?).with(anything, /NetworkManager/).and_return(network_manager) + end it "sets the hostname if not set" do comm.stub_command("hostname -f | grep '^#{name}$'", exit_code: 1) cap.change_host_name(machine, name) - expect(comm.received_commands[1]).to match(/hostname -F \/etc\/hostname/) - expect(comm.received_commands[1]).to match(/hostname.sh start/) + expect(comm.received_commands[1]).to match(/echo 'banana-rama' > \/etc\/hostname/) + end + + context "when hostnamectl is in use" do + let(:hostnamectl) { true } + + it "sets hostname with hostnamectl" do + cap.change_host_name(machine, name) + expect(comm.received_commands[2]).to match(/hostnamectl/) + end + end + + context "when hostnamectl is not in use" do + let(:hostnamectl) { false } + + it "sets hostname with hostname command" do + cap.change_host_name(machine, name) + expect(comm.received_commands[2]).to match(/hostname -F/) + end + end + + context "restarts the network" do + context "when networkd is in use" do + let(:networkd) { true } + + it "restarts networkd with systemctl" do + cap.change_host_name(machine, name) + expect(comm.received_commands[3]).to match(/systemctl restart systemd-networkd/) + end + end + + context "when NetworkManager is in use" do + let(:networkd) { false } + let(:network_manager) { true } + + it "restarts NetworkManager with systemctl" do + cap.change_host_name(machine, name) + expect(comm.received_commands[3]).to match(/systemctl restart NetworkManager/) + end + end + + context "when networkd and NetworkManager are not in use" do + let(:networkd) { false } + let(:network_manager) { false } + + it "restarts the network using service" do + cap.change_host_name(machine, name) + expect(comm.received_commands[3]).to match(/networking restart/) + end + end + + context "when systemd is not in use" do + let(:systemd) { false } + + it "restarts the network using service" do + cap.change_host_name(machine, name) + expect(comm.received_commands[3]).to match(/networking restart/) + end + end end it "does not set the hostname if unset" do