Merge pull request #2663 from acharlieh/el-refactor-change-host-name

guests/redhat: refactoring of EL Change Host Name
This commit is contained in:
Mitchell Hashimoto 2013-12-16 10:20:21 -08:00
commit 46c1760105
3 changed files with 397 additions and 8 deletions

View File

@ -3,16 +3,93 @@ module VagrantPlugins
module Cap
class ChangeHostName
def self.change_host_name(machine, name)
machine.communicate.tap do |comm|
# Only do this if the hostname is not already set
if !comm.test("sudo hostname | grep --line-regexp '#{name}'")
comm.sudo("sed -i 's/\\(HOSTNAME=\\).*/\\1#{name}/' /etc/sysconfig/network")
comm.sudo("hostname #{name}")
comm.sudo("sed -i 's@^\\(127[.]0[.]0[.]1[[:space:]]\\+\\)@\\1#{name} #{name.split('.')[0]} @' /etc/hosts")
comm.sudo("sed -i 's/\\(DHCP_HOSTNAME=\\).*/\\1\"#{name.split('.')[0]}\"/' /etc/sysconfig/network-scripts/ifcfg-*")
comm.sudo("service network restart")
new(machine, name).change!
end
attr_reader :machine, :new_hostname
def initialize(machine, new_hostname)
@machine = machine
@new_hostname = new_hostname
end
def change!
return unless should_change?
update_sysconfig
update_hostname
update_etc_hosts
update_dhcp_hostnames
restart_networking
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 #{short_hostname}"
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

View File

@ -0,0 +1,67 @@
require File.expand_path("../../../../../base", __FILE__)
require File.expand_path("../../../support/shared/redhat_like_host_name_examples", __FILE__)
describe "VagrantPlugins::GuestRedHat::Cap::ChangeHostName" do
let(:described_class) do
VagrantPlugins::GuestRedHat::Plugin.components.guest_capabilities[:redhat].get(:change_host_name)
end
let(:machine) { double("machine") }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
machine.stub(:communicate).and_return(communicator)
communicator.stub_command('hostname -f', stdout: old_hostname)
communicator.expect_command('hostname -f')
end
after do
communicator.verify_expectations!
end
context 'when oldhostname is qualified' do
let(:old_hostname) { 'oldhostname.olddomain.tld' }
let(:similar_hostname) {'oldhostname'}
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'
include_examples 'swapping qualified hostname in /etc/hosts'
end
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'
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)
communicator.received_commands.to_set.should_not == communicator.expected_commands.keys.to_set
end
end
end

View File

@ -0,0 +1,245 @@
shared_examples 'a partial redhat-like host name change' do
shared_examples 'shared between newhostname styles' do
it 'updates hostname on the machine with the new short hostname' do
communicator.expect_command(%q(hostname newhostname))
described_class.change_host_name(machine, new_hostname)
end
it 'sets dhcp_hostname with the provided short hostname' do
communicator.expect_command(%q(sed -i 's/\\(DHCP_HOSTNAME=\\).*/\\1"newhostname"/' /etc/sysconfig/network-scripts/ifcfg-*))
described_class.change_host_name(machine, new_hostname)
end
it 'restarts networking' do
communicator.expect_command(%q(service network restart))
described_class.change_host_name(machine, new_hostname)
end
end
context 'when newhostname is qualified' do
let(:new_hostname) {'newhostname.newdomain.tld'}
include_examples 'shared between newhostname styles'
it 'updates sysconfig with the provided full hostname' do
communicator.expect_command(%q(sed -i 's/\\(HOSTNAME=\\).*/\\1newhostname.newdomain.tld/' /etc/sysconfig/network))
described_class.change_host_name(machine, new_hostname)
end
end
context 'when newhostname is simple' do
let(:new_hostname) {'newhostname'}
include_examples 'shared between newhostname styles'
it 'updates sysconfig with as much hostname as is available' do
communicator.expect_command(%q(sed -i 's/\\(HOSTNAME=\\).*/\\1newhostname/' /etc/sysconfig/network))
described_class.change_host_name(machine, new_hostname)
end
end
end
shared_examples 'a full redhat-like host name change' do
include_examples 'a partial redhat-like host name change'
it "does nothing when the provided hostname is not different" do
described_class.change_host_name(machine, old_hostname)
communicator.received_commands.to_set.should == communicator.expected_commands.keys.to_set
end
it "does more when the provided hostname is a similar version" do
described_class.change_host_name(machine, similar_hostname)
communicator.received_commands.to_set.should_not == communicator.expected_commands.keys.to_set
end
end
shared_examples 'mutating /etc/hosts helpers' do
let(:sed_command) do
# Here we run the change_host_name through and extract the recorded sed
# command from the dummy communicator
described_class.change_host_name(machine, new_hostname)
communicator.received_commands.find { |cmd| cmd =~ %r(^sed .* /etc/hosts$) }
end
# Now we extract the regexp from that sed command so we can do some
# verification on it
let(:expression) { sed_command.sub(%r{^sed -i '\(.*\)' /etc/hosts$}, "\1") }
let(:search) { Regexp.new(expression.split('@')[1].gsub(/\\/,'')) }
let(:replace) { expression.split('@')[2] }
end
shared_examples 'inserting hostname in /etc/hosts' do
include_examples 'mutating /etc/hosts helpers'
context 'when target hostname is qualified' do
let(:new_hostname) {'newhostname.newdomain.tld'}
it 'works with a basic file' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname.newdomain.tld newhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
end
context 'when target hostname is simple' do
let(:new_hostname) {'newhostname'}
it 'works with a basic file' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
end
end
shared_examples 'swapping simple hostname in /etc/hosts' do
include_examples 'mutating /etc/hosts helpers'
context 'when target hostname is qualified' do
let(:new_hostname) {'newhostname.newdomain.tld'}
it 'works with a basic file' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname.newdomain.tld newhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
it 'does not touch suffixed hosts' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname.newdomain.tld newhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
end
context 'when target hostname is simple' do
let(:new_hostname) {'newhostname'}
it 'works with a basic file' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
it 'does not touch suffixed hosts' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
end
end
shared_examples 'swapping qualified hostname in /etc/hosts' do
include_examples 'mutating /etc/hosts helpers'
context 'when target hostname is qualified' do
let(:new_hostname) {'newhostname.newdomain.tld'}
it 'works with a basic file' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname.olddomain.tld oldhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname.newdomain.tld newhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
it 'does not touch suffixed hosts' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname.olddomain.tld oldhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname.newdomain.tld newhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
end
context 'when target hostname is simple' do
let(:new_hostname) {'newhostname'}
it 'works with a basic file' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname.olddomain.tld oldhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
it 'does not touch suffixed hosts' do
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
127.0.0.1 oldhostname.olddomain.tld oldhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
ETC_HOSTS
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
127.0.0.1 newhostname oldhostname.nope localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
RESULT
end
end
end