Exemplo n.º 1
0
    def test_make_configdrive(self, mock_popen):
        fake_process = mock.Mock(returncode=0)
        fake_process.communicate.return_value = ('', '')
        mock_popen.return_value = fake_process

        with utils.tempdir() as dirname:
            utils.make_configdrive(dirname)

        mock_popen.assert_called_once_with(self.genisoimage_cmd,
                                           stderr=subprocess.PIPE,
                                           stdout=subprocess.PIPE)
        fake_process.communicate.assert_called_once_with()
Exemplo n.º 2
0
    def test_make_configdrive(self, mock_popen):
        fake_process = mock.Mock(returncode=0)
        fake_process.communicate.return_value = ('', '')
        mock_popen.return_value = fake_process

        with utils.tempdir() as dirname:
            utils.make_configdrive(dirname)

        mock_popen.assert_called_once_with(self.genisoimage_cmd,
                                           stderr=subprocess.PIPE,
                                           stdout=subprocess.PIPE)
        fake_process.communicate.assert_called_once_with()
Exemplo n.º 3
0
    def set_provision_state(self, node_uuid, state, configdrive=None,
                            cleansteps=None):
        """Set the provision state for the node.

        :param node_uuid: The UUID or name of the node.
        :param state: The desired provision state. One of 'active', 'deleted',
             'rebuild', 'inspect', 'provide', 'manage', 'clean', 'abort'.
        :param configdrive: A gzipped, base64-encoded configuration drive
            string OR the path to the configuration drive file OR the path to
            a directory containing the config drive files. In case it's a
            directory, a config drive will be generated from it. This is only
            valid when setting state to 'active'.
        :param cleansteps: The clean steps as a list of clean-step
            dictionaries; each dictionary should have keys 'interface' and
            'step', and optional key 'args'. This must be specified (and is
            only valid) when setting provision-state to 'clean'.
        :raises: InvalidAttribute if there was an error with the clean steps
        :returns: The status of the request
        """

        path = "%s/states/provision" % node_uuid
        body = {'target': state}
        if configdrive:
            if os.path.isfile(configdrive):
                with open(configdrive, 'rb') as f:
                    configdrive = f.read()
            if os.path.isdir(configdrive):
                configdrive = utils.make_configdrive(configdrive)

            body['configdrive'] = configdrive
        elif cleansteps:
            body['clean_steps'] = cleansteps

        return self.update(path, body, http_method='PUT')
Exemplo n.º 4
0
    def set_provision_state(self, node_uuid, state, configdrive=None):
        path = "%s/states/provision" % node_uuid
        body = {'target': state}
        if configdrive:
            if os.path.isfile(configdrive):
                with open(configdrive, 'rb') as f:
                    configdrive = f.read()
            if os.path.isdir(configdrive):
                configdrive = utils.make_configdrive(configdrive)

            body['configdrive'] = configdrive
        return self._update(self._path(path), body, method='PUT')
Exemplo n.º 5
0
    def set_provision_state(self,
                            node_uuid,
                            state,
                            configdrive=None,
                            cleansteps=None,
                            rescue_password=None,
                            os_ironic_api_version=None):
        """Set the provision state for the node.

        :param node_uuid: The UUID or name of the node.
        :param state: The desired provision state. One of 'active', 'deleted',
             'rebuild', 'inspect', 'provide', 'manage', 'clean', 'abort',
             'rescue', 'unrescue'.
        :param configdrive: A gzipped, base64-encoded configuration drive
            string OR the path to the configuration drive file OR the path to
            a directory containing the config drive files OR a dictionary to
            build config drive from. In case it's a directory, a config drive
            will be generated from it. In case it's a dictionary, a config
            drive will be generated on the server side (requires API version
            1.56). This is only valid when setting state to 'active'.
        :param cleansteps: The clean steps as a list of clean-step
            dictionaries; each dictionary should have keys 'interface' and
            'step', and optional key 'args'. This must be specified (and is
            only valid) when setting provision-state to 'clean'.
        :param rescue_password: A string to be used as the login password
            inside the rescue ramdisk once a node is rescued. This must be
            specified (and is only valid) when setting 'state' to 'rescue'.
        :param os_ironic_api_version: String version (e.g. "1.35") to use for
            the request.  If not specified, the client's default is used.
        :raises: InvalidAttribute if there was an error with the clean steps
        :returns: The status of the request
        """

        path = "%s/states/provision" % node_uuid
        body = {'target': state}
        if configdrive:
            if not isinstance(configdrive, dict):
                if os.path.isfile(configdrive):
                    with open(configdrive, 'rb') as f:
                        configdrive = f.read()
                if os.path.isdir(configdrive):
                    configdrive = utils.make_configdrive(configdrive)

            body['configdrive'] = configdrive
        elif cleansteps:
            body['clean_steps'] = cleansteps
        elif rescue_password:
            body['rescue_password'] = rescue_password

        return self.update(path,
                           body,
                           http_method='PUT',
                           os_ironic_api_version=os_ironic_api_version)
Exemplo n.º 6
0
    def set_provision_state(self, node_uuid, state, configdrive=None):
        path = "%s/states/provision" % node_uuid
        body = {'target': state}
        if configdrive:
            if os.path.isfile(configdrive):
                with open(configdrive, 'rb') as f:
                    configdrive = f.read()
            if os.path.isdir(configdrive):
                configdrive = utils.make_configdrive(configdrive)

            body['configdrive'] = configdrive
        return self._update(self._path(path), body, method='PUT')
 def create(self, repository, create_files=True):
     # Create a temp folder
     try:
         tmp_dir = tempfile.mkdtemp('_configdrive')
         tmp_dir_base = os.path.join(tmp_dir,'ec2', 'latest')
         os.makedirs(tmp_dir_base)
         if create_files:
             if not repository.exists(self.node_uuid + '/ec2/latest/'):
                 repository.mkdir(self.node_uuid + '/ec2/latest')
         # user-data.json
         user_data_tmp_file = os.path.join(tmp_dir_base,'user-data')
         cfgdrive_user_json = json.dumps(
             self.user_data, indent=4, separators=(',', ': '))
         with open(user_data_tmp_file, 'w') as outfile:
             outfile.write(cfgdrive_user_json)
         if create_files:
             repository.put(
                 StringIO.StringIO(cfgdrive_user_json),
                 self.node_uuid + '/ec2/latest/user-data')
         # meta-data.json
         meta_data_tmp_file = os.path.join(tmp_dir_base,'meta-data.json')
         cfgdrive_meta_json = json.dumps(
             self.meta_data, indent=4, separators=(',', ': '))
         with open(meta_data_tmp_file, 'w') as outfile:
             outfile.write(cfgdrive_meta_json)
         if create_files:
             repository.put(
                 StringIO.StringIO(cfgdrive_meta_json),
                 self.node_uuid + '/ec2/latest/meta-data.json')
         # Create it using Ironic utils
         self.logger.debug("Creating configdrive volume")
         configdrive = utils.make_configdrive(tmp_dir)
         self.logger.debug("Uploading configdrive to repository")
         repository.put(StringIO.StringIO(configdrive), self.configdrive_id)
     except ironic_exception.ClientException as e:
         msg = "Error creating configdrive volume %s" % (e)
         self.logger.error(msg)
         raise ConfigdriveError(msg)
     except RepositoryError as e:
         msg = "Cannot save configdrive '%s' in the repository: %s" % (self.configdrive_id, e)
         self.logger.error(msg)
         raise ConfigdriveError(msg)
     except Exception as e:
         msg = "%s: %s" % (type(e).__name__, e)
         self.logger.error(msg)
         raise ConfigdriveError(msg)
     finally:
         if tmp_dir:
             shutil.rmtree(tmp_dir)
     self.logger.info("Configdrive created with id '%s' in the repository" % (self.configdrive_id))
     return self.configdrive_id
Exemplo n.º 8
0
    def set_provision_state(self, node_uuid, state, configdrive=None,
                            cleansteps=None, rescue_password=None,
                            os_ironic_api_version=None):
        """Set the provision state for the node.

        :param node_uuid: The UUID or name of the node.
        :param state: The desired provision state. One of 'active', 'deleted',
             'rebuild', 'inspect', 'provide', 'manage', 'clean', 'abort',
             'rescue', 'unrescue'.
        :param configdrive: A gzipped, base64-encoded configuration drive
            string OR the path to the configuration drive file OR the path to
            a directory containing the config drive files OR a dictionary to
            build config drive from. In case it's a directory, a config drive
            will be generated from it. In case it's a dictionary, a config
            drive will be generated on the server side (requires API version
            1.56). This is only valid when setting state to 'active'.
        :param cleansteps: The clean steps as a list of clean-step
            dictionaries; each dictionary should have keys 'interface' and
            'step', and optional key 'args'. This must be specified (and is
            only valid) when setting provision-state to 'clean'.
        :param rescue_password: A string to be used as the login password
            inside the rescue ramdisk once a node is rescued. This must be
            specified (and is only valid) when setting 'state' to 'rescue'.
        :param os_ironic_api_version: String version (e.g. "1.35") to use for
            the request.  If not specified, the client's default is used.
        :raises: InvalidAttribute if there was an error with the clean steps
        :returns: The status of the request
        """

        path = "%s/states/provision" % node_uuid
        body = {'target': state}
        if configdrive:
            if not isinstance(configdrive, dict):
                if os.path.isfile(configdrive):
                    with open(configdrive, 'rb') as f:
                        configdrive = f.read()
                if os.path.isdir(configdrive):
                    configdrive = utils.make_configdrive(configdrive)

            body['configdrive'] = configdrive
        elif cleansteps:
            body['clean_steps'] = cleansteps
        elif rescue_password:
            body['rescue_password'] = rescue_password

        return self.update(path, body, http_method='PUT',
                           os_ironic_api_version=os_ironic_api_version)
Exemplo n.º 9
0
    def set_provision_state(self,
                            node_uuid,
                            state,
                            configdrive=None,
                            cleansteps=None):
        """Set the provision state for the node.

        :param node_uuid: The UUID or name of the node.
        :param state: The desired provision state. One of 'active', 'deleted',
             'rebuild', 'inspect', 'provide', 'manage', 'clean', 'abort'.
        :param configdrive: A gzipped, base64-encoded configuration drive
            string OR the path to the configuration drive file OR the path to
            a directory containing the config drive files. In case it's a
            directory, a config drive will be generated from it. This is only
            valid when setting state to 'active'.
        :param cleansteps: The clean steps as a list of clean-step
            dictionaries; each dictionary should have keys 'interface' and
            'step', and optional key 'args'. This must be specified (and is
            only valid) when setting provision-state to 'clean'.
        :raises: InvalidAttribute if there was an error with the clean steps
        :returns: The status of the request
        """

        path = "%s/states/provision" % node_uuid
        body = {'target': state}
        if configdrive:
            if os.path.isfile(configdrive):
                with open(configdrive, 'rb') as f:
                    configdrive = f.read()
            if os.path.isdir(configdrive):
                configdrive = utils.make_configdrive(configdrive)

            body['configdrive'] = configdrive
        elif cleansteps:
            body['clean_steps'] = cleansteps

        return self.update(path, body, http_method='PUT')