From b91c167b191be6633e060d9772cf1c5ccc2b0291 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Sun, 5 Jun 2016 19:08:44 -0400 Subject: [PATCH] guests/redhat: Change host name in one command --- plugins/guests/redhat/cap/change_host_name.rb | 118 ++++-------------- .../redhat/cap/change_host_name_test.rb | 74 ++++------- 2 files changed, 49 insertions(+), 143 deletions(-) diff --git a/plugins/guests/redhat/cap/change_host_name.rb b/plugins/guests/redhat/cap/change_host_name.rb index 2520904ec..64691b8f5 100644 --- a/plugins/guests/redhat/cap/change_host_name.rb +++ b/plugins/guests/redhat/cap/change_host_name.rb @@ -3,104 +3,38 @@ module VagrantPlugins module Cap class ChangeHostName def self.change_host_name(machine, name) - new(machine, name).change! - end + comm = machine.communicate - attr_reader :machine, :new_hostname + if !comm.test("hostname -f | grep -w '#{name}'", sudo: false) + basename = name.split('.', 2)[0] + comm.sudo <<-EOH.gsub(/^ {14}/, '') + # Update sysconfig + sed -i 's/\\(HOSTNAME=\\).*/\\1#{name}/' /etc/sysconfig/network - def initialize(machine, new_hostname) - @machine = machine - @new_hostname = new_hostname - end + # Update DNS + sed -i 's/\\(DHCP_HOSTNAME=\\).*/\\1\"#{basename}\"/' /etc/sysconfig/network-scripts/ifcfg-* - def change! - return unless should_change? + # Set the hostname - use hostnamectl if available + echo '#{name}' > /etc/hostname + if command -v hostnamectl; then + hostnamectl set-hostname '#{name}' + else + hostname '#{name}' + fi - case machine.guest.capability("flavor") - when :rhel_7 - update_hostname_rhel7 - update_etc_hosts - else - update_sysconfig - update_hostname - update_etc_hosts - update_dhcp_hostnames - restart_networking + # Remove comments and blank lines from /etc/hosts + sed -i'' -e 's/#.*$//' -e '/^$/d' /etc/hosts + + # Prepend ourselves to /etc/hosts + grep -w '#{name}' /etc/hosts || { + sed -i'' '1i 127.0.0.1\\t#{name}\\t#{basename}' /etc/hosts + } + + # Restart network + service network restart + EOH end end - - def should_change? - new_hostname != current_hostname - end - - def current_hostname - @current_hostname ||= get_current_hostname - end - - def get_current_hostname - hostname = '' - block = lambda do |type, data| - if type == :stdout - hostname += data.chomp - end - end - - execute 'hostname -f', error_check: false, &block - execute 'hostname',&block if hostname.empty? - /localhost(\..*)?/.match(hostname) ? '' : hostname - end - - def update_sysconfig - sudo "sed -i 's/\\(HOSTNAME=\\).*/\\1#{fqdn}/' /etc/sysconfig/network" - end - - def update_hostname - sudo "hostname #{fqdn}" - end - - def update_hostname_rhel7 - sudo "hostnamectl set-hostname #{fqdn}" - end - - # /etc/hosts should resemble: - # 127.0.0.1 host.fqdn.com host localhost ... - def update_etc_hosts - s = '[[:space:]]' - current_fqdn = Regexp.escape(current_hostname) - current_short = Regexp.escape(current_hostname.split('.').first.to_s) - currents = "\\(#{current_fqdn}#{s}\\+\\|#{current_short}#{s}\\+\\)*" unless current_hostname.empty? - local_ip = '127[.]0[.]0[.]1' - search = "^\\(#{local_ip}#{s}\\+\\)#{currents}" - replace = "\\1#{fqdn} " - replace = "#{replace}#{short_hostname} " unless fqdn == short_hostname - expression = ['s', search, replace,''].join('@') - - sudo "sed -i '#{expression}' /etc/hosts" - end - - def update_dhcp_hostnames - sudo "sed -i 's/\\(DHCP_HOSTNAME=\\).*/\\1\"#{short_hostname}\"/' /etc/sysconfig/network-scripts/ifcfg-*" - end - - def restart_networking - sudo 'service network restart' - end - - def fqdn - new_hostname - end - - def short_hostname - new_hostname.split('.').first - end - - def execute(cmd, opts=nil, &block) - machine.communicate.execute(cmd, opts, &block) - end - - def sudo(cmd, opts=nil, &block) - machine.communicate.sudo(cmd, opts, &block) - end end end end diff --git a/test/unit/plugins/guests/redhat/cap/change_host_name_test.rb b/test/unit/plugins/guests/redhat/cap/change_host_name_test.rb index 558bb5983..84da01b20 100644 --- a/test/unit/plugins/guests/redhat/cap/change_host_name_test.rb +++ b/test/unit/plugins/guests/redhat/cap/change_host_name_test.rb @@ -1,70 +1,42 @@ -require File.expand_path("../../../../../base", __FILE__) -require File.expand_path("../../../support/shared/redhat_like_host_name_examples", __FILE__) +require_relative "../../../../base" describe "VagrantPlugins::GuestRedHat::Cap::ChangeHostName" do - let(:described_class) do - VagrantPlugins::GuestRedHat::Plugin.components.guest_capabilities[:redhat].get(:change_host_name) + let(:caps) do + VagrantPlugins::GuestRedHat::Plugin + .components + .guest_capabilities[:redhat] end + let(:machine) { double("machine") } - let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } - let(:guest) { double("guest") } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } before do - allow(guest).to receive(:capability).and_return(nil) - allow(machine).to receive(:communicate).and_return(communicator) - allow(machine).to receive(:guest).and_return(guest) - communicator.stub_command('hostname -f', stdout: old_hostname) - communicator.expect_command('hostname -f') + allow(machine).to receive(:communicate).and_return(comm) end after do - communicator.verify_expectations! + comm.verify_expectations! end - context 'when oldhostname is qualified' do - let(:old_hostname) { 'oldhostname.olddomain.tld' } - let(:similar_hostname) {'oldhostname'} + describe ".change_host_name" do + let(:cap) { caps.get(:change_host_name) } - it_behaves_like 'a full redhat-like host name change' + let(:name) { "banana-rama.example.com" } - include_examples 'inserting hostname in /etc/hosts' - include_examples 'swapping simple hostname in /etc/hosts' - include_examples 'swapping qualified hostname in /etc/hosts' - end + it "sets the hostname" do + comm.stub_command("hostname -f | grep -w '#{name}'", exit_code: 1) - context 'when oldhostname is simple' do - let(:old_hostname) { 'oldhostname' } - let(:similar_hostname) {'oldhostname.olddomain.tld'} - - it_behaves_like 'a full redhat-like host name change' - - include_examples 'inserting hostname in /etc/hosts' - include_examples 'swapping simple hostname in /etc/hosts' - - context 'and is only able to be determined by hostname (without -f)' do - before do - communicator.stub_command('hostname -f',nil) - communicator.stub_command('hostname', stdout: old_hostname) - communicator.expect_command('hostname') - end - - it_behaves_like 'a full redhat-like host name change' - - include_examples 'inserting hostname in /etc/hosts' - include_examples 'swapping simple hostname in /etc/hosts' + cap.change_host_name(machine, name) + expect(comm.received_commands[1]).to match(/\/etc\/sysconfig\/network/) + expect(comm.received_commands[1]).to match(/\/etc\/sysconfig\/network-scripts\/ifcfg/) + expect(comm.received_commands[1]).to match(/hostnamectl set-hostname '#{name}'/) + expect(comm.received_commands[1]).to match(/service network restart/) end - end - context 'when the short version of hostname is localhost' do - let(:old_hostname) { 'localhost.olddomain.tld' } - - it_behaves_like 'a partial redhat-like host name change' - - include_examples 'inserting hostname in /etc/hosts' - - it "does more even when the provided hostname is not different" do - described_class.change_host_name(machine, old_hostname) - expect(communicator.received_commands.to_set).not_to eq(communicator.expected_commands.keys.to_set) + it "does not change the hostname if already set" do + comm.stub_command("hostname -f | grep -w '#{name}'", exit_code: 0) + cap.change_host_name(machine, name) + expect(comm.received_commands.size).to eq(1) end end end