f393a513d7
When we add content to rc.local, if the file already exists then we need to make sure we add the content after a new line explicitly Fixes LP #1089668 Change-Id: I35be1496703b302f732363fa76ce832505eed599
199 lines
8.0 KiB
Python
199 lines
8.0 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
#
|
|
# Copyright (C) 2012 Red Hat, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import sys
|
|
|
|
from nova import test
|
|
from nova.tests import fakeguestfs
|
|
from nova.virt.disk import api as diskapi
|
|
from nova.virt.disk.vfs import guestfs as vfsguestfs
|
|
|
|
|
|
class VirtDiskTest(test.TestCase):
|
|
|
|
def setUp(self):
|
|
super(VirtDiskTest, self).setUp()
|
|
sys.modules['guestfs'] = fakeguestfs
|
|
vfsguestfs.guestfs = fakeguestfs
|
|
|
|
def test_inject_data_key(self):
|
|
|
|
vfs = vfsguestfs.VFSGuestFS("/some/file", "qcow2")
|
|
vfs.setup()
|
|
|
|
diskapi._inject_key_into_fs("mysshkey", vfs)
|
|
|
|
self.assertTrue("/root/.ssh" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/root/.ssh"],
|
|
{'isdir': True, 'gid': 0, 'uid': 0, 'mode': 0700})
|
|
self.assertTrue("/root/.ssh/authorized_keys" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/root/.ssh/authorized_keys"],
|
|
{'isdir': False,
|
|
'content': "Hello World\n# The following ssh " +
|
|
"key was injected by Nova\nmysshkey\n",
|
|
'gid': 100,
|
|
'uid': 100,
|
|
'mode': 0700})
|
|
|
|
vfs.teardown()
|
|
|
|
def test_inject_data_key_with_selinux(self):
|
|
|
|
vfs = vfsguestfs.VFSGuestFS("/some/file", "qcow2")
|
|
vfs.setup()
|
|
|
|
vfs.make_path("etc/selinux")
|
|
vfs.make_path("etc/rc.d")
|
|
diskapi._inject_key_into_fs("mysshkey", vfs)
|
|
|
|
self.assertTrue("/etc/rc.d/rc.local" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/etc/rc.d/rc.local"],
|
|
{'isdir': False,
|
|
'content': "Hello World#!/bin/sh\n# Added by " +
|
|
"Nova to ensure injected ssh keys " +
|
|
"have the right context\nrestorecon " +
|
|
"-RF root/.ssh 2>/dev/null || :\n",
|
|
'gid': 100,
|
|
'uid': 100,
|
|
'mode': 0700})
|
|
|
|
self.assertTrue("/root/.ssh" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/root/.ssh"],
|
|
{'isdir': True, 'gid': 0, 'uid': 0, 'mode': 0700})
|
|
self.assertTrue("/root/.ssh/authorized_keys" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/root/.ssh/authorized_keys"],
|
|
{'isdir': False,
|
|
'content': "Hello World\n# The following ssh " +
|
|
"key was injected by Nova\nmysshkey\n",
|
|
'gid': 100,
|
|
'uid': 100,
|
|
'mode': 0700})
|
|
|
|
vfs.teardown()
|
|
|
|
def test_inject_data_key_with_selinux_append_with_newline(self):
|
|
|
|
vfs = vfsguestfs.VFSGuestFS("/some/file", "qcow2")
|
|
vfs.setup()
|
|
|
|
vfs.replace_file("/etc/rc.d/rc.local", "#!/bin/sh\necho done")
|
|
vfs.make_path("etc/selinux")
|
|
vfs.make_path("etc/rc.d")
|
|
diskapi._inject_key_into_fs("mysshkey", vfs)
|
|
|
|
self.assertTrue("/etc/rc.d/rc.local" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/etc/rc.d/rc.local"],
|
|
{'isdir': False,
|
|
'content': "#!/bin/sh\necho done\n# Added "
|
|
"by Nova to ensure injected ssh keys have "
|
|
"the right context\nrestorecon -RF "
|
|
"root/.ssh 2>/dev/null || :\n",
|
|
'gid': 100,
|
|
'uid': 100,
|
|
'mode': 0700})
|
|
vfs.teardown()
|
|
|
|
def test_inject_net(self):
|
|
|
|
vfs = vfsguestfs.VFSGuestFS("/some/file", "qcow2")
|
|
vfs.setup()
|
|
|
|
diskapi._inject_net_into_fs("mynetconfig", vfs)
|
|
|
|
self.assertTrue("/etc/network/interfaces" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/etc/network/interfaces"],
|
|
{'content': 'mynetconfig',
|
|
'gid': 100,
|
|
'isdir': False,
|
|
'mode': 0700,
|
|
'uid': 100})
|
|
vfs.teardown()
|
|
|
|
def test_inject_metadata(self):
|
|
vfs = vfsguestfs.VFSGuestFS("/some/file", "qcow2")
|
|
vfs.setup()
|
|
|
|
diskapi._inject_metadata_into_fs([{"key": "foo",
|
|
"value": "bar"},
|
|
{"key": "eek",
|
|
"value": "wizz"}], vfs)
|
|
|
|
self.assertTrue("/meta.js" in vfs.handle.files)
|
|
self.assertEquals(vfs.handle.files["/meta.js"],
|
|
{'content': '{"foo": "bar", ' +
|
|
'"eek": "wizz"}',
|
|
'gid': 100,
|
|
'isdir': False,
|
|
'mode': 0700,
|
|
'uid': 100})
|
|
vfs.teardown()
|
|
|
|
def test_inject_admin_password(self):
|
|
vfs = vfsguestfs.VFSGuestFS("/some/file", "qcow2")
|
|
vfs.setup()
|
|
|
|
def fake_salt():
|
|
return "1234567890abcdef"
|
|
|
|
self.stubs.Set(diskapi, '_generate_salt', fake_salt)
|
|
|
|
vfs.handle.write("/etc/shadow",
|
|
"root:$1$12345678$xxxxx:14917:0:99999:7:::\n" +
|
|
"bin:*:14495:0:99999:7:::\n" +
|
|
"daemon:*:14495:0:99999:7:::\n")
|
|
|
|
vfs.handle.write("/etc/passwd",
|
|
"root:x:0:0:root:/root:/bin/bash\n" +
|
|
"bin:x:1:1:bin:/bin:/sbin/nologin\n" +
|
|
"daemon:x:2:2:daemon:/sbin:/sbin/nologin\n")
|
|
|
|
diskapi._inject_admin_password_into_fs("123456", vfs)
|
|
|
|
self.assertEquals(vfs.handle.files["/etc/passwd"],
|
|
{'content': "root:x:0:0:root:/root:/bin/bash\n" +
|
|
"bin:x:1:1:bin:/bin:/sbin/nologin\n" +
|
|
"daemon:x:2:2:daemon:/sbin:" +
|
|
"/sbin/nologin\n",
|
|
'gid': 100,
|
|
'isdir': False,
|
|
'mode': 0700,
|
|
'uid': 100})
|
|
shadow = vfs.handle.files["/etc/shadow"]
|
|
|
|
# if the encrypted password is only 13 characters long, then
|
|
# nova.virt.disk.api:_set_password fell back to DES.
|
|
if len(shadow['content']) == 91:
|
|
self.assertEquals(shadow,
|
|
{'content': "root:12tir.zIbWQ3c" +
|
|
":14917:0:99999:7:::\n" +
|
|
"bin:*:14495:0:99999:7:::\n" +
|
|
"daemon:*:14495:0:99999:7:::\n",
|
|
'gid': 100,
|
|
'isdir': False,
|
|
'mode': 0700,
|
|
'uid': 100})
|
|
else:
|
|
self.assertEquals(shadow,
|
|
{'content': "root:$1$12345678$a4ge4d5iJ5vw" +
|
|
"vbFS88TEN0:14917:0:99999:7:::\n" +
|
|
"bin:*:14495:0:99999:7:::\n" +
|
|
"daemon:*:14495:0:99999:7:::\n",
|
|
'gid': 100,
|
|
'isdir': False,
|
|
'mode': 0700,
|
|
'uid': 100})
|
|
vfs.teardown()
|