예제 #1
0
 def test_target_is_ubuntu_core_noncore_target(self):
     self.target = self.tmp_dir()
     non_core_path = os.path.join(self.target, 'curtin')
     util.ensure_dir(non_core_path)
     self.assertTrue(os.path.isdir(non_core_path))
     is_core = curthooks.target_is_ubuntu_core(self.target)
     self.assertFalse(is_core)
예제 #2
0
파일: install.py 프로젝트: mojodna/curtin
def clear_install_log(logfile):
    """Clear the installation log, so no previous installation is present."""
    util.ensure_dir(os.path.dirname(logfile))
    try:
        open(logfile, 'w').close()
    except Exception:
        pass
예제 #3
0
    def test_collect_logs_main_sources_config_from_save_install_config(self):
        """collect_logs_main uses /root/curtin-install-cfg.yaml config."""
        savefile = self.tmp_path('curtin-install-cfg.log', _dir=self.new_root)
        write_file(savefile, 'install:\n  log_file: /tmp/savefile.log\n')
        packdir = self.tmp_path('configs', _dir=self.new_root)
        ensure_dir(packdir)
        unusedcfg = os.path.join(packdir, 'config-001.yaml')
        write_file(unusedcfg, 'install:\n  log_file: /tmp/unused.log\n')
        utcnow = datetime.utcnow()
        datestr = utcnow.strftime('%Y-%m-%d-%H-%M')
        tardir = self.tmp_path('curtin-logs-%s' % datestr, _dir=self.tmpdir)
        curtin_config = self.tmp_path('curtin-config', _dir=tardir)

        self.assertEqual('/curtin/configs',
                         collect_logs.CURTIN_PACK_CONFIG_DIR)
        self.add_patch('curtin.commands.collect_logs.SAVE_INSTALL_CONFIG',
                       '_idir',
                       new=savefile,
                       autospec=None)
        self.add_patch('curtin.commands.collect_logs.CURTIN_PACK_CONFIG_DIR',
                       '_cdir',
                       new=packdir,
                       autospec=None)
        self.add_patch('shutil.rmtree', 'm_rmtree')
        with mock.patch('sys.stderr'):
            with mock.patch('curtin.commands.collect_logs.datetime') as m_dt:
                with self.assertRaises(SystemExit) as context_manager:
                    m_dt.utcnow.return_value = utcnow
                    collect_logs.collect_logs_main(FakeArgs('my.tar'))
        self.assertEqual('0', str(context_manager.exception))
        expected_cfg = {'install': {'log_file': '/tmp/savefile.log'}}
        with open(curtin_config, 'r') as f:
            self.assertEqual(expected_cfg, json.loads(f.read()))
예제 #4
0
    def test_curtin_error_unmount_doesnt_lose_exception(self):
        """Confirm unmount:disable skips unmounting, keeps exception"""
        working_dir = self.tmp_path('working', _dir=self.new_root)
        ensure_dir(working_dir)
        write_file(self.logfile, 'old log')

        # Providing two dd images raises an error, set unmount: disabled
        myargs = FakeArgs(
            config={'install':
                    {'log_file': self.logfile, 'unmount': 'disabled'}},
            source=['dd-raw:https://localhost/raw_images/centos-6-3.img',
                    'dd-raw:https://localhost/cant/provide/two/images.img'],
            reportstack=FakeReportStack())
        self.add_patch(
            'curtin.commands.collect_logs.create_log_tarfile', 'm_tar')
        self.add_patch(
            'curtin.commands.install.copy_install_log', 'm_copy_log')
        self.add_patch('curtin.util.do_umount', 'm_umount')

        rv = 42
        with self.assertRaises(Exception):
            rv = install.cmd_install(myargs)

        # make sure install.cmd_install does not return a value, but Exception
        self.assertEqual(42, rv)
        self.assertEqual(0, self.m_umount.call_count)
        self.assertEqual(1, self.m_copy_log.call_count)
예제 #5
0
 def _setup_nodes(self, sessions, connection):
     # setup iscsi_nodes dir (<fakeroot>/etc/iscsi/nodes) with content
     for s in sessions:
         sdir = os.path.join(self.iscsi_nodes, s)
         connpath = os.path.join(sdir, connection)
         util.ensure_dir(sdir)
         util.write_file(connpath, content="")
예제 #6
0
 def test_target_is_ubuntu_core(self):
     self.target = self.tmp_dir()
     ubuntu_core_path = os.path.join(self.target, 'system-data',
                                     'var/lib/snapd')
     util.ensure_dir(ubuntu_core_path)
     self.assertTrue(os.path.isdir(ubuntu_core_path))
     is_core = curthooks.target_is_ubuntu_core(self.target)
     self.assertTrue(is_core)
예제 #7
0
 def setUp(self):
     super(TestBlockIscsiDisconnect, self).setUp()
     self.add_patch('curtin.block.iscsi.util.subp', 'mock_subp')
     self.add_patch('curtin.block.iscsi.iscsiadm_sessions',
                    'mock_iscsi_sessions')
     # fake target_root + iscsi nodes dir
     self.target_path = self.tmp_dir()
     self.iscsi_nodes = os.path.join(self.target_path, 'etc/iscsi/nodes')
     util.ensure_dir(self.iscsi_nodes)
예제 #8
0
 def setUp(self):
     super(TestCollectLogs, self).setUp()
     self.new_root = self.tmp_dir()
     self.add_patch('curtin.util.subp', 'mock_subp')
     self.mock_subp.return_value = ('', '')
     self.tmpdir = self.tmp_path('mytemp', _dir=self.new_root)
     ensure_dir(self.tmpdir)  # Create it because we mock mkdtemp
     self.add_patch('tempfile.mkdtemp',
                    'm_mkdtemp',
                    return_value=self.tmpdir)
예제 #9
0
 def test_target_dir_by_default_is_under_workd(self):
     """WorkingDir does not require target in config."""
     tmp_d = self.tmp_dir()
     work_d = self.tmp_path("work_d", tmp_d)
     ensure_dir(work_d)
     with mock.patch("curtin.commands.install.tempfile.mkdtemp",
                     return_value=work_d) as m_mkdtemp:
         wd = install.WorkingDir({})
     self.assertEqual(1, m_mkdtemp.call_count)
     self.assertTrue(wd.target.startswith(work_d + "/"))
예제 #10
0
 def _enable_loaders(bootid):
     efi_path = 'boot/efi/EFI'
     target_efi_path = os.path.join(self.target, efi_path)
     loaders = [
         os.path.join(target_efi_path, bootid, 'shimx64.efi'),
         os.path.join(target_efi_path, 'BOOT', 'BOOTX64.EFI'),
         os.path.join(target_efi_path, bootid, 'grubx64.efi'),
     ]
     for loader in loaders:
         util.ensure_dir(os.path.dirname(loader))
         with open(loader, 'w+') as fh:
             fh.write('\n')
예제 #11
0
    def test_prefer_existing_bootx_loader_with_no_shim(self):
        # touch all loaders in target filesystem
        loaders = self._possible_loaders()[1:]
        for loader in loaders:
            tloader = os.path.join(self.target, loader)
            util.ensure_dir(os.path.dirname(tloader))
            with open(tloader, 'w+') as fh:
                fh.write('\n')

        found = install_grub.find_efi_loader(self.target, self.bootid)
        self.assertTrue(
            found.endswith(os.path.join(self.efi_path, 'BOOT', 'BOOTX64.EFI')))
예제 #12
0
def prepare_grub_dir(target, grub_cfg):
    util.ensure_dir(os.path.dirname(target_path(target, grub_cfg)))

    # LP: #1179940 . The 50-cloudig-settings.cfg file is written by the cloud
    # images build and defines/override some settings. Disable it.
    ci_cfg = target_path(
        target,
        os.path.join(os.path.dirname(grub_cfg), "50-cloudimg-settings.cfg"))

    if os.path.exists(ci_cfg):
        LOG.debug('grub: moved %s out of the way', ci_cfg)
        shutil.move(ci_cfg, ci_cfg + '.disabled')
예제 #13
0
 def setUp(self):
     super(TestCreateTar, self).setUp()
     self.new_root = self.tmp_dir()
     self.utcnow = datetime.utcnow()
     self.tardir = 'curtin-logs-%s' % self.utcnow.strftime('%Y-%m-%d-%H-%M')
     self.add_patch('curtin.commands.collect_logs._collect_system_info',
                    'm_sys_info')
     self.tmpdir = self.tmp_path('mytemp', _dir=self.new_root)
     ensure_dir(self.tmpdir)  # Create it because we mock mkdtemp
     self.add_patch('tempfile.mkdtemp',
                    'm_mkdtemp',
                    return_value=self.tmpdir)
예제 #14
0
 def test_target_dir_with_content_raises_error(self):
     """WorkingDir raises ValueError on populated target_d."""
     tmp_d = self.tmp_dir()
     work_d = self.tmp_path("work_d", tmp_d)
     target_d = self.tmp_path("target_d", tmp_d)
     ensure_dir(work_d)
     ensure_dir(target_d)
     write_file(self.tmp_path("somefile.txt", target_d), "sometext")
     with mock.patch("curtin.commands.install.tempfile.mkdtemp",
                     return_value=work_d):
         with self.assertRaises(ValueError):
             install.WorkingDir({'install': {'target': target_d}})
예제 #15
0
    def test_prefer_shim_loader(self):
        # touch loaders in target filesystem
        loaders = self._possible_loaders()
        for loader in loaders:
            tloader = os.path.join(self.target, loader)
            util.ensure_dir(os.path.dirname(tloader))
            with open(tloader, 'w+') as fh:
                fh.write('\n')

        found = install_grub.find_efi_loader(self.target, self.bootid)
        self.assertTrue(
            found.endswith(
                os.path.join(self.efi_path, self.bootid, 'shimx64.efi')))
예제 #16
0
 def test_target_dir_may_exist(self):
     """WorkingDir supports existing empty target directory."""
     tmp_d = self.tmp_dir()
     work_d = self.tmp_path("work_d", tmp_d)
     target_d = self.tmp_path("target_d", tmp_d)
     ensure_dir(work_d)
     ensure_dir(target_d)
     with mock.patch("curtin.commands.install.tempfile.mkdtemp",
                     return_value=work_d) as m_mkdtemp:
         workingdir = install.WorkingDir({'install': {'target': target_d}})
     self.assertEqual(1, m_mkdtemp.call_count)
     self.assertEqual(target_d, workingdir.target)
     self.assertEqual(target_d, workingdir.env().get('TARGET_MOUNT_POINT'))
예제 #17
0
    def test_curtin_error_copies_config_and_error_tarfile_defaults(self):
        """On curtin error, install error_tarfile is created with all logs.

        Curtin config, install log and error_tarfile are copied into target.
        """
        working_dir = self.tmp_path('working', _dir=self.new_root)
        ensure_dir(working_dir)
        target_dir = self.tmp_path('target', _dir=working_dir)
        write_file(self.logfile, 'old log')
        # Providing two dd images raises an error
        myargs = FakeArgs(
            config={'install': {'log_file': self.logfile}},
            source=['dd-raw:https://localhost/raw_images/centos-6-3.img',
                    'dd-raw:https://localhost/cant/provide/two/images.img'],
            reportstack=FakeReportStack())
        self.add_patch(
            'curtin.commands.collect_logs.create_log_tarfile', 'm_tar')
        self.add_patch(
            'curtin.commands.install.copy_install_log', 'm_copy_log')
        self.add_patch(
            'curtin.commands.install.tempfile.mkdtemp', 'm_mkdtemp')
        self.m_mkdtemp.return_value = working_dir
        with self.assertRaises(ValueError) as context_manager:
            install.cmd_install(myargs)
        self.assertEqual(
            'You may not use more than one disk image',
            str(context_manager.exception))
        expected_cfg = copy.deepcopy(install.CONFIG_BUILTIN)
        expected_cfg['install']['log_file'] = self.logfile
        expected_cfg['proxy'] = {}
        expected_cfg['sources'] = {
            '00_cmdline': {
                'type': 'dd-raw',
                'uri': 'https://localhost/raw_images/centos-6-3.img'},
            '01_cmdline': {
                'type': 'dd-raw',
                'uri': 'https://localhost/cant/provide/two/images.img'}}
        expected_cfg['write_files'] = {
            'curtin_install_cfg': {
                'owner': 'root:root', 'permissions': '0400',
                'path': '/root/curtin-install-cfg.yaml',
                'content': config.dump_config(expected_cfg)}}
        # Call create_log_tarfile to collect error logs.
        self.assertEqual(
            [mock.call('/var/log/curtin/curtin-error-logs.tar', expected_cfg)],
            self.m_tar.call_args_list)
        self.assertEqual(
            [mock.call(self.logfile, target_dir, '/root/curtin-install.log')],
            self.m_copy_log.call_args_list)
예제 #18
0
파일: helpers.py 프로젝트: tjjh89017/curtin
def populate_dir(path, files):
    if not os.path.exists(path):
        os.makedirs(path)
    ret = []
    for (name, content) in files.items():
        p = os.path.sep.join([path, name])
        util.ensure_dir(os.path.dirname(p))
        with open(p, "wb") as fp:
            if isinstance(content, util.binary_type):
                fp.write(content)
            else:
                fp.write(content.encode('utf-8'))
            fp.close()
        ret.append(p)

    return ret
예제 #19
0
파일: install.py 프로젝트: mojodna/curtin
    def __init__(self, config):
        top_d = tempfile.mkdtemp()
        state_d = os.path.join(top_d, 'state')
        scratch_d = os.path.join(top_d, 'scratch')
        for p in (state_d, scratch_d):
            os.mkdir(p)

        target_d = config.get('install', {}).get('target')
        if not target_d:
            target_d = os.path.join(top_d, 'target')
        try:
            util.ensure_dir(target_d)
        except OSError as e:
            raise ValueError(
                "Unable to create target directory '%s': %s" %
                (target_d, e))
        if os.listdir(target_d) != []:
            raise ValueError(
                "Provided target dir '%s' was not empty." % target_d)

        netconf_f = os.path.join(state_d, 'network_config')
        netstate_f = os.path.join(state_d, 'network_state')
        interfaces_f = os.path.join(state_d, 'interfaces')
        config_f = os.path.join(state_d, 'config')
        fstab_f = os.path.join(state_d, 'fstab')

        with open(config_f, "w") as fp:
            json.dump(config, fp)

        # just touch these files to make sure they exist
        for f in (interfaces_f, config_f, fstab_f, netconf_f, netstate_f):
            with open(f, "ab") as fp:
                pass

        self.scratch = scratch_d
        self.target = target_d
        self.top = top_d
        self.interfaces = interfaces_f
        self.netconf = netconf_f
        self.netstate = netstate_f
        self.fstab = fstab_f
        self.config = config
        self.config_file = config_f
예제 #20
0
    def test_collect_logs_main_sources_config_from_pack_configs(self):
        """collect_logs_main sources all configs from /curtin/configs dir."""
        savefile = self.tmp_path('absentinstall.log', _dir=self.new_root)
        packdir = self.tmp_path('configs', _dir=self.new_root)
        utcnow = datetime.utcnow()
        datestr = utcnow.strftime('%Y-%m-%d-%H-%M')
        tardir = self.tmp_path('curtin-logs-%s' % datestr, _dir=self.tmpdir)
        ensure_dir(packdir)
        cfg1 = os.path.join(packdir, 'config-001.yaml')
        cfg2 = os.path.join(packdir, 'config-002.yaml')
        write_file(cfg1, 'install:\n  log_file: /tmp/my.log\n')
        write_file(cfg2, 'install:\n  post_files: [/tmp/post.log]\n')

        self.assertEqual('/curtin/configs',
                         collect_logs.CURTIN_PACK_CONFIG_DIR)
        self.add_patch('curtin.commands.collect_logs.SAVE_INSTALL_CONFIG',
                       '_idir',
                       new=savefile,
                       autospec=None)
        self.add_patch('curtin.commands.collect_logs.CURTIN_PACK_CONFIG_DIR',
                       '_cdir',
                       new=packdir,
                       autospec=None)
        self.add_patch('shutil.rmtree', 'm_rmtree')
        with mock.patch('sys.stderr'):
            with mock.patch('curtin.commands.collect_logs.datetime') as m_dt:
                with self.assertRaises(SystemExit) as context_manager:
                    m_dt.utcnow.return_value = utcnow
                    collect_logs.collect_logs_main(FakeArgs('my.tar'))
        self.assertEqual('0', str(context_manager.exception))
        self.assertEqual(['config-001.yaml', 'config-002.yaml'],
                         sorted(os.listdir(packdir)))
        curtin_config = self.tmp_path('curtin-config', _dir=tardir)
        # Config parts are merged with CONFIG_BUILTIN
        expected_cfg = copy.deepcopy(CONFIG_BUILTIN)
        expected_cfg['install'] = {
            'log_file': '/tmp/my.log',
            'post_files': ['/tmp/post.log', '/tmp/my.log'],
            'error_tarfile': '/var/log/curtin/curtin-error-logs.tar'
        }
        with open(curtin_config, 'r') as f:
            self.assertEqual(expected_cfg, json.loads(f.read()))
예제 #21
0
    def test_curthooks_cloud_config_remove_disabled(self, mock_handle_cc):
        self.target = self.tmp_dir()
        uc_cloud = os.path.join(self.target, 'system-data', 'etc/cloud')
        cc_disabled = os.path.join(uc_cloud, 'cloud-init.disabled')
        cc_path = os.path.join(uc_cloud, 'cloud.cfg.d')

        util.ensure_dir(uc_cloud)
        util.write_file(cc_disabled, content="# disable cloud-init\n")
        cfg = {
            'cloudconfig': {
                'file1': {
                    'content': "Hello World!\n",
                }
            }
        }
        self.assertTrue(os.path.exists(cc_disabled))
        curthooks.ubuntu_core_curthooks(cfg, target=self.target)

        mock_handle_cc.assert_called_with(cfg.get('cloudconfig'),
                                          base_dir=cc_path)
        self.assertFalse(os.path.exists(cc_disabled))
예제 #22
0
 def setUp(self):
     super(TestReplaceGrubCmdlineLinuxDefault, self).setUp()
     self.target = self.tmp_dir()
     self.grubconf = "/etc/default/grub"
     self.target_grubconf = paths.target_path(self.target, self.grubconf)
     util.ensure_dir(os.path.dirname(self.target_grubconf))