diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 252b0db55..2c5dd4734 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -149,49 +149,3 @@ class TestVirtDisk(test.TestCase): self.executes.pop() self.assertEqual(self.executes, expected_commands) - - -class TestVirtDiskPaths(test.TestCase): - def setUp(self): - super(TestVirtDiskPaths, self).setUp() - - real_execute = utils.execute - - def nonroot_execute(*cmd_parts, **kwargs): - kwargs.pop('run_as_root', None) - return real_execute(*cmd_parts, **kwargs) - - self.stubs.Set(utils, 'execute', nonroot_execute) - - def test_check_safe_path(self): - if tests.utils.is_osx(): - self.skipTest("Unable to test on OSX") - ret = disk_api._join_and_check_path_within_fs('/foo', 'etc', - 'something.conf') - self.assertEquals(ret, '/foo/etc/something.conf') - - def test_check_unsafe_path(self): - if tests.utils.is_osx(): - self.skipTest("Unable to test on OSX") - self.assertRaises(exception.Invalid, - disk_api._join_and_check_path_within_fs, - '/foo', 'etc/../../../something.conf') - - def test_inject_files_with_bad_path(self): - if tests.utils.is_osx(): - self.skipTest("Unable to test on OSX") - self.assertRaises(exception.Invalid, - disk_api._inject_file_into_fs, - '/tmp', '/etc/../../../../etc/passwd', - 'hax') - - def test_inject_metadata(self): - if tests.utils.is_osx(): - self.skipTest("Unable to test on OSX") - with utils.tempdir() as tmpdir: - meta_objs = [{"key": "foo", "value": "bar"}] - metadata = {"foo": "bar"} - disk_api._inject_metadata_into_fs(meta_objs, tmpdir) - json_file = os.path.join(tmpdir, 'meta.js') - json_data = jsonutils.loads(open(json_file).read()) - self.assertEqual(metadata, json_data) diff --git a/nova/tests/test_virt_disk.py b/nova/tests/test_virt_disk.py new file mode 100644 index 000000000..cc69462d7 --- /dev/null +++ b/nova/tests/test_virt_disk.py @@ -0,0 +1,163 @@ +# 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 api as vfsapi +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_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}) + self.assertEquals(vfs.handle.files["/etc/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()