guests/{ubuntu,debian}: fix change_host_name for trailing dots [GH-2610]
When `/etc/hosts` contained a FQDN with a trailing dot, the `\b` in the sed expression would not match, since dot is not considered to be a word character. Fix this by regexp-escaping the hostname search, and matching the end of the line on optional space followed by additional characters. Also add some tests that extract the regexp used by sed and verify that it does what we want. These will hopefully serve us in the future if we ever need to test additional edge cases.
This commit is contained in:
parent
25b0018759
commit
abe0731d2e
|
@ -47,8 +47,8 @@ module VagrantPlugins
|
|||
# 127.0.1.1 host.fqdn.com host.fqdn host
|
||||
def update_etc_hosts
|
||||
ip_address = '([0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
search = "^(#{ip_address})\\s+#{current_hostname}\\b.*$"
|
||||
replace = "\\1\\t#{fqdn} #{short_hostname}"
|
||||
search = "^(#{ip_address})\\s+#{Regexp.escape(current_hostname)}(\\s.*)?$"
|
||||
replace = "\\1 #{fqdn} #{short_hostname}"
|
||||
expression = ['s', search, replace, 'g'].join('@')
|
||||
|
||||
sudo("sed -ri '#{expression}' /etc/hosts")
|
||||
|
|
|
@ -7,10 +7,11 @@ describe "VagrantPlugins::GuestDebian::Cap::ChangeHostName" do
|
|||
end
|
||||
let(:machine) { double("machine") }
|
||||
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
|
||||
let(:old_hostname) { 'oldhostname.olddomain.tld' }
|
||||
|
||||
before do
|
||||
machine.stub(:communicate).and_return(communicator)
|
||||
communicator.stub_command('hostname -f', stdout: 'oldhostname.olddomain.tld')
|
||||
communicator.stub_command('hostname -f', stdout: old_hostname)
|
||||
end
|
||||
|
||||
after do
|
||||
|
|
|
@ -4,15 +4,6 @@ shared_examples "a debian-like host name change" do
|
|||
described_class.change_host_name(machine, 'newhostname.newdomain.tld')
|
||||
end
|
||||
|
||||
it "flips out the old hostname in /etc/hosts" do
|
||||
sed_find = '^(([0-9]{1,3}\.){3}[0-9]{1,3})\s+oldhostname.olddomain.tld\b.*$'
|
||||
sed_replace = '\1\tnewhostname.newdomain.tld newhostname'
|
||||
communicator.expect_command(
|
||||
%Q(sed -ri 's@#{sed_find}@#{sed_replace}@g' /etc/hosts)
|
||||
)
|
||||
described_class.change_host_name(machine, 'newhostname.newdomain.tld')
|
||||
end
|
||||
|
||||
it "updates mailname to prevent problems with the default mailer" do
|
||||
communicator.expect_command(%q(hostname --fqdn > /etc/mailname))
|
||||
described_class.change_host_name(machine, 'newhostname.newdomain.tld')
|
||||
|
@ -22,4 +13,77 @@ shared_examples "a debian-like host name change" do
|
|||
described_class.change_host_name(machine, 'oldhostname.olddomain.tld')
|
||||
communicator.received_commands.should == ['hostname -f']
|
||||
end
|
||||
|
||||
describe "flipping out the old hostname in /etc/hosts" 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, 'newhostname.newdomain.tld')
|
||||
communicator.received_commands.find { |cmd| cmd =~ /^sed/ }
|
||||
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 -ri '\(.*\)' /etc/hosts$}, "\1") }
|
||||
let(:search) { Regexp.new(expression.split('@')[1], Regexp::EXTENDED) }
|
||||
let(:replace) { expression.split('@')[2] }
|
||||
|
||||
it "works on an simple /etc/hosts file" do
|
||||
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 oldhostname.olddomain.tld oldhostname
|
||||
ETC_HOSTS
|
||||
|
||||
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
|
||||
|
||||
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 newhostname.newdomain.tld newhostname
|
||||
RESULT
|
||||
end
|
||||
|
||||
it "does not modify lines which contain similar hostnames" do
|
||||
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 oldhostname.olddomain.tld oldhostname
|
||||
|
||||
# common prefix, but different fqdn
|
||||
192.168.12.34 oldhostname.olddomain.tld.different
|
||||
|
||||
# different characters at the dot
|
||||
192.168.34.56 oldhostname-olddomain.tld
|
||||
ETC_HOSTS
|
||||
|
||||
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
|
||||
|
||||
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 newhostname.newdomain.tld newhostname
|
||||
|
||||
# common prefix, but different fqdn
|
||||
192.168.12.34 oldhostname.olddomain.tld.different
|
||||
|
||||
# different characters at the dot
|
||||
192.168.34.56 oldhostname-olddomain.tld
|
||||
RESULT
|
||||
end
|
||||
|
||||
context "when the old fqdn has a trailing dot" do
|
||||
let(:old_hostname) { 'oldhostname.withtrailing.dot.' }
|
||||
|
||||
it "modifies /etc/hosts properly" do
|
||||
original_etc_hosts = <<-ETC_HOSTS.gsub(/^ */, '')
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 oldhostname.withtrailing.dot. oldhostname
|
||||
ETC_HOSTS
|
||||
|
||||
modified_etc_hosts = original_etc_hosts.gsub(search, replace)
|
||||
|
||||
modified_etc_hosts.should == <<-RESULT.gsub(/^ */, '')
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 newhostname.newdomain.tld newhostname
|
||||
RESULT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,11 @@ describe "VagrantPlugins::GuestUbuntu::Cap::ChangeHostName" do
|
|||
end
|
||||
let(:machine) { double("machine") }
|
||||
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
|
||||
let(:old_hostname) {'oldhostname.olddomain.tld' }
|
||||
|
||||
before do
|
||||
machine.stub(:communicate).and_return(communicator)
|
||||
communicator.stub_command('hostname -f', stdout: 'oldhostname.olddomain.tld')
|
||||
communicator.stub_command('hostname -f', stdout: old_hostname)
|
||||
end
|
||||
|
||||
after do
|
||||
|
|
Loading…
Reference in New Issue