Support setting hostname

We get a name value in the config drive meta_data.json, lets use this
for setting a hostname. Also write out a hosts entry for 127.0.1.1 to
hostname.

Change-Id: Ia9155bc565ad79af44d88acc06759be2bf4e5f20
This commit is contained in:
Gregory Haynes 2015-06-25 21:19:12 +00:00
parent ec00af334e
commit ff66735e38
2 changed files with 69 additions and 4 deletions

View File

@ -18,6 +18,7 @@ import argparse
import json
import os
import platform
import re
import subprocess
import sys
import time
@ -325,6 +326,42 @@ def write_ssh_keys(args):
finish_files(files_to_write, args)
def set_hostname_from_config_drive(args):
if args.noop:
return
config_drive = os.path.join(args.root, 'mnt/config')
meta_data_path = '%s/openstack/latest/meta_data.json' % config_drive
if not os.path.exists(meta_data_path):
return
meta_data = json.load(open(meta_data_path))
if 'name' not in meta_data:
return
hostname = meta_data['name']
ret = subprocess.call(['hostname', hostname])
if ret != 0:
raise RuntimeError('Error setting hostname')
else:
with open('/etc/hostname', 'w') as fh:
fh.write(hostname)
fh.write('\n')
# See if we already have a hosts entry for hostname
prog = re.compile('^127.0.1.1 .*%s' % hostname)
match = None
with open('/etc/hosts') as fh:
match = prog.match(fh.read())
# Write out a hosts entry for hostname
if match is None:
with open('/etc/hosts', 'w+') as fh:
fh.write('127.0.1.1 %s\n' % hostname)
def main():
parser = argparse.ArgumentParser(description="Static network config")
parser.add_argument(
@ -340,12 +377,17 @@ def main():
default=None, help="Interface to process")
parser.add_argument(
'--ssh', dest='ssh', action='store_true', help="Write ssh key")
parser.add_argument(
'--hostname', dest='hostname', action='store_true',
help="Set the hostname if name is available in config drive.")
parser.add_argument(
'--skip-network', dest='skip', action='store_true',
help="Do not write network info")
args = parser.parse_args()
if args.ssh:
write_ssh_keys(args)
if args.hostname:
set_hostname_from_config_drive(args)
if args.interface != 'lo' and not args.skip:
write_network_info_from_config_drive(args)
return 0

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os
import fixtures
@ -54,13 +55,15 @@ class TestGlean(base.BaseTestCase):
def open_side_effect(*args, **kwargs):
if (args[0].startswith('/etc/network') or
args[0].startswith('/etc/sysconfig/network-scripts') or
args[0].startswith('/etc/resolv.conf')):
args[0].startswith('/etc/resolv.conf') or
args[0] in ('/etc/hostname', '/etc/hosts')):
try:
mock_handle = self.file_handle_mocks[args[0]]
except KeyError:
mock_handle = mock.Mock()
mock_handle.__enter__ = mock.Mock(return_value=mock_handle)
mock_handle.__exit__ = mock.Mock()
mock_handle.read.return_value = ''
self.file_handle_mocks[args[0]] = mock_handle
return mock_handle
elif args[0].startswith('/sys/class/net'):
@ -113,11 +116,15 @@ class TestGlean(base.BaseTestCase):
self.useFixture(fixtures.MonkeyPatch('platform.dist', fake_distro))
def _assert_network_output(self, distro, provider):
self._patch_argv([])
def _assert_distro_provider(self, distro, provider):
self._patch_argv(['--hostname'])
self._patch_files(provider)
self._patch_distro(distro)
mock_call = mock.Mock()
mock_call.return_value = 0
self.useFixture(fixtures.MonkeyPatch('subprocess.call', mock_call))
cmd.main()
output_filename = '%s.%s.network.out' % (provider, distro.lower())
@ -144,5 +151,21 @@ class TestGlean(base.BaseTestCase):
write_handle = self.file_handle_mocks[dest].write
write_handle.assert_called_once_with(content)
# Check hostname
meta_data_path = 'mnt/config/openstack/latest/meta_data.json'
hostname = None
with open(os.path.join(sample_data_path, provider,
meta_data_path)) as fh:
meta_data = json.load(fh)
hostname = meta_data['name']
mock_call.assert_called_once_with(['hostname', hostname])
self.file_handle_mocks['/etc/hostname'].write.assert_has_calls(
[mock.call(hostname), mock.call('\n')])
# Check hosts entry
self.file_handle_mocks['/etc/hosts'].write.assert_called_once_with(
'127.0.1.1 %s\n' % hostname)
def test_glean(self):
self._assert_network_output(self.distro, self.style)
self._assert_distro_provider(self.distro, self.style)