Exemplo n.º 1
0
 def _on_update_status(self, _):
     container = self.unit.get_container("splunk")
     if not self.state.auto_start:
         self.unit.status = MaintenanceStatus("splunk service is paused")
     elif not container.get_service("splunk").is_running():
         self.unit.status = BlockedStatus("splunk service isn't running")
     else:
         self.unit.status = ActiveStatus("ready")
Exemplo n.º 2
0
def test_not_kubeflow_model():
    # Tests that unit will BlockStatus if deployed outside a model named kubeflow
    # Remove when this bug is resolved: https://github.com/kubeflow/kubeflow/issues/6136
    harness = Harness(Operator)
    harness.begin_with_initial_hooks()
    assert harness.charm.model.unit.status == BlockedStatus(
        "kubeflow-dashboard must be deployed to model named `kubeflow`:"
        " https://git.io/J6d35")
Exemplo n.º 3
0
    def _on_install(self, event):
        """Perform installation operations for slurmctld."""
        self.unit.set_workload_version(Path("version").read_text().strip())

        self.unit.status = WaitingStatus("Installing slurmctld")

        custom_repo = self.config.get("custom-slurm-repo")
        successful_installation = self._slurm_manager.install(custom_repo)

        if successful_installation:
            self._stored.slurm_installed = True

            # Store the munge_key and jwt_rsa key in the stored state.
            # NOTE: Use leadership settings instead of stored state when
            # leadership settings support becomes available in the framework.
            if self._is_leader():
                # NOTE the backup controller should also have the jwt and munge
                #      keys configured. We should move these information to the
                #      peer relation.
                self._stored.jwt_rsa = self._slurm_manager.generate_jwt_rsa()
                self._stored.munge_key = self._slurm_manager.get_munge_key()
                self._slurm_manager.configure_jwt_rsa(self.get_jwt_rsa())
            else:
                # NOTE: the secondary slurmctld should get the jwt and munge
                #       keys from the peer relation here
                logger.debug("secondary slurmctld")

            # all slurmctld should restart munged here, as it would assure
            # munge is working
            self._slurm_manager.restart_munged()
        else:
            self.unit.status = BlockedStatus("Error installing slurmctld")
            event.defer()

        logger.debug("## Retrieving etcd resource to install it")
        try:
            etcd_path = self.model.resources.fetch("etcd")
            logger.debug(f"## Found etcd resource: {etcd_path}")
        except ModelError:
            logger.error("## Missing etcd resource")
            self.unit.status = BlockedStatus("Missing etcd resource")
            event.defer()
            return
        self._etcd.install(etcd_path)

        self._check_status()
Exemplo n.º 4
0
 def _on_update_status(self, _):
     path = self._image_publish_dir() + '/.data'
     if os.path.isdir(path):
         stat = os.stat(path)
         self.model.unit.status = \
             ActiveStatus("Publishes: {}".format(time.ctime(stat.st_mtime)))
     else:
         self.model.unit.status = BlockedStatus("Images not synchronized")
Exemplo n.º 5
0
    def test_custom_status_check_default_config(self):
        self.harness.disable_hooks()
        self.harness.begin()

        self.assertFalse(self.harness.charm.custom_status_check())
        expected_status = BlockedStatus('Missing configs: {}'.format(
            list(self.REQUIRED_CHARM_CONFIG_BY_DEFAULT.keys())))
        self.assertEqual(self.harness.charm.unit.status, expected_status)
Exemplo n.º 6
0
    def _on_config_changed(self, _):
        """Reconfigure the Grafana tester."""
        container = self.unit.get_container(self._name)
        if not container.can_connect():
            self.unit.status = BlockedStatus("Waiting for Pebble ready")
            return

        self.unit.status = ActiveStatus()
Exemplo n.º 7
0
 def verify_credentials(self):
     proxy = self.get_ssh_proxy()
     verified, _ = proxy.verify_credentials()
     if verified:
         self.unit.status = ActiveStatus()
     else:
         self.unit.status = BlockedStatus("Invalid SSH credentials.")
     return verified
Exemplo n.º 8
0
 def test_start_no_certificate(self):
     charm._host = Mock()
     harness = Harness(charm.CertbotCharm)
     self.addCleanup(harness.cleanup)
     harness.begin()
     harness.update_config(self._config(harness.charm))
     harness.charm.on.start.emit()
     self.assertEqual(harness.charm.model.unit.status,
                      BlockedStatus('certificate not yet acquired.'))
Exemplo n.º 9
0
 def _on_check_status_and_write_config(self, event):
     slurm_installed = self._stored.slurm_installed
     slurm_config = self._stored.config_available
     logger.debug("##### inside check status and write config ######")
     if not (slurm_installed and slurm_config):
         if not slurm_config:
             self.unit.status = BlockedStatus(
                 "NEED RELATION TO SLURM-CONFIGURATOR")
         else:
             self.unit.status = BlockedStatus("SLURM NOT INSTALLED")
         event.defer()
         return
     else:
         logger.debug("##### STATUS CONFIRMED ######")
         config = dict(self._slurmrestd.get_slurm_config())
         logger.debug(config)
         self.slurm_manager.render_config_and_restart(config)
         self.unit.status = ActiveStatus("Slurmrestd Available")
Exemplo n.º 10
0
    def start(self, event):
        """Event handler for StartEevnt."""

        if self.model.config['kind'] not in ('ingress', 'egress'):
            self.model.unit.status = BlockedStatus(
                'Config item `kind` must be set')
            return

        if not self.model.relations['istio-pilot']:
            self.model.unit.status = BlockedStatus(
                "Waiting for istio-pilot relation")
            return

        if not ((pilot := self.interfaces["istio-pilot"])
                and pilot.get_data()):
            self.model.unit.status = WaitingStatus(
                "Waiting for istio-pilot relation data")
            return
Exemplo n.º 11
0
    def _on_check_status_and_write_config(self, event):
        slurm_installed = self._stored.slurm_installed
        slurmctld_acquired = self._stored.slurmctld_available
        slurm_config = self._stored.slurm_config

        if not (slurm_installed and slurmctld_acquired and slurm_config):
            if not slurmctld_acquired:
                self.unit.status = BlockedStatus("NEED RELATION TO SLURMCTLD")
            elif not slurm_config:
                self.unit.status = BlockedStatus("NEED SLURM CONFIG")
            else:
                self.unit.status = BlockedStatus("SLURM NOT INSTALLED")
            event.defer()
            return
        else:
            config = dict(self._stored.slurm_config)
            self.slurm_manager.render_config_and_restart(config)
            self.unit.status = ActiveStatus("Slurmrestd Available")
Exemplo n.º 12
0
 def _on_start(self, _):
     self.model.unit.status = BlockedStatus("certificate not yet acquired.")
     try:
         # attempt to get a certificate using the defaults, don't
         # worry if it fails.
         self._get_certificate()
     except Exception as err:
         logger.info("could not automatically acquire certificate",
                     exc_info=err)
Exemplo n.º 13
0
    def _on_check_status_and_write_config(self, event):
        slurmdbd_acquired = self.slurmdbd.slurmdbd_acquired
        slurmd_acquired = self.slurmd.slurmd_acquired
        if not (slurmdbd_acquired and slurmd_acquired):
            if not slurmdbd_acquired:
                self.unit.status = BlockedStatus("NEED RELATION TO SLURMDBD")
            else:
                self.unit.status = BlockedStatus("NEED RELATION TO SLURMD")
            event.defer()
        else:
            try:
                slurm_config = json.loads(self.slurmd.get_slurm_config())
            except json.JSONDecodeError as e:
                logger.debug(e)

            self.slurm_ops_manager.render_config_and_restart(slurm_config)
            logger.debug(slurm_config)
            self.unit.status = ActiveStatus("Slurmctld Available")
 def _check_mandatory_config(self):
     charm_config = self.framework.model.config
     missing_config = []
     for config in self.MANDATORY_CONFIG:
         if charm_config.get(config) is None:
             missing_config.append(config)
     if missing_config:
         self.unit.status = BlockedStatus("Missing mandatory configuration option {}".format(missing_config))
         return False
     return True
Exemplo n.º 15
0
 def _get_peers_for_context(self, peers):
     try:
         peers = yaml.load(io.StringIO(peers))
     except yaml.YAMLError:
         self.unit.status = BlockedStatus(
             "'peers' config property is not valid YAML.")
         return None
     invalid_peers = [
         p for p in peers if not self._is_peer_config_valid(peers[p])
     ]
     if invalid_peers:
         self.unit.status = BlockedStatus(
             f"Peers with invalid configuration: {invalid_peers}")
         return None
     peers = list(peers.values())
     for p in peers:
         p['thruk_id'] = hashlib.md5(
             p['nagios_context'].encode('utf-8')).hexdigest()
     return peers
Exemplo n.º 16
0
    def _check_status(self):
        slurm_installed = self._stored.slurm_installed
        config_available = self._stored.config_available

        if not (slurm_installed and config_available):
            self.unit.status = BlockedStatus(
                "NEED RELATION TO SLURM CONFIGURATOR")
            return False
        else:
            return True
Exemplo n.º 17
0
 def test_check_config_with_missing_option(self):
     self.harness.set_leader(True)
     missing_password_config = {'port': 9000, 'admin-password': ''}
     with self.assertLogs(level='WARNING') as logger:
         self.harness.update_config(missing_password_config)
         msg = 'ERROR:charm:Need admin-password config option before setting pod spec.'
         self.assertEqual(sorted(logger.output), [msg])
         self.assertEqual(
             self.harness.model.unit.status,
             BlockedStatus("Need 'admin-password' config option."))
Exemplo n.º 18
0
    def test_validate_config_missing_product_id(self):
        self.harness.update_config({'product-id': ''})

        self.harness.disable_hooks()
        self.harness.begin()

        self.assertFalse(self.harness.charm._validate_config())
        expected_status = BlockedStatus('Missing configuration: {}'.format(
            ['product-id']))
        self.assertEqual(self.harness.charm.unit.status, expected_status)
Exemplo n.º 19
0
    def configure_pod(self, _=None) -> NoReturn:
        """Assemble the pod spec and apply it, if possible."""
        missing = self._missing_relations()
        if missing:
            status = "Waiting for {0} relation{1}"
            self.unit.status = BlockedStatus(
                status.format(missing, "s" if "," in missing else ""))
            return

        if not self.unit.is_leader():
            self.unit.status = ActiveStatus("ready")
            return

        self.unit.status = MaintenanceStatus("Assembling pod spec")

        # Fetch image information
        try:
            self.unit.status = MaintenanceStatus("Fetching image information")
            image_info = self.image.fetch()
        except OCIImageResourceError:
            self.unit.status = BlockedStatus(
                "Error fetching image information")
            return

        if self.state.upf_host:
            try:
                pod_spec = make_pod_spec(
                    image_info,
                    self.model.config,
                    self.relation_state,
                    self.model.app.name,
                )
            except ValueError as exc:
                logger.exception("Config/Relation data validation error")
                self.unit.status = BlockedStatus(str(exc))
                return

        if self.state.pod_spec != pod_spec:
            self.model.pod.set_spec(pod_spec)
            self.state.pod_spec = pod_spec

        self.unit.status = ActiveStatus("ready")
Exemplo n.º 20
0
 def test_install_apt_packages(self, _add_package, _update):
     # Call the method with some packages to install
     self.harness.charm._install_apt_packages(["curl", "vim"])
     # Check that apt is called with the correct arguments
     _update.assert_called_once()
     _add_package.assert_called_with(["curl", "vim"])
     # Now check that if an exception is raised we do the right logging
     _add_package.reset_mock()
     _add_package.return_value = 1
     _add_package.side_effect = apt.PackageNotFoundError
     self.harness.charm._install_apt_packages(["curl", "vim"])
     self.assertEqual(self.harness.charm.unit.status,
                      BlockedStatus("Failed to install packages"))
     # Now check that if an exception is raised we do the right logging
     _add_package.reset_mock()
     _add_package.return_value = 1
     _add_package.side_effect = apt.PackageError
     self.harness.charm._install_apt_packages(["curl", "vim"])
     self.assertEqual(self.harness.charm.unit.status,
                      BlockedStatus("Failed to install packages"))
Exemplo n.º 21
0
 def _on_config_changed(self, event):
     if self.model.config['protocol'] != 'layer2':
         self.unit.status = BlockedStatus(
             'Invalid protocol; '
             'only "layer2" currently supported')
         return
     current_config_hash = self._config_hash()
     if current_config_hash != self._stored.config_hash:
         self._stored.started = False
         self._stored.config_hash = current_config_hash
         self._on_start(event)
Exemplo n.º 22
0
    def _on_upgrade(self, event):
        """Upgrade the charm."""
        slurm_config = self._assemble_slurm_config()

        if not slurm_config:
            self.unit.status = BlockedStatus(
                "Cannot generate slurm_config, defering upgrade.")
            event.defer()
            return

        self._slurm_manager.upgrade(slurm_config)
Exemplo n.º 23
0
 def test_on_config_changed_when_unit_is_leader_but_image_fetch_breaks(
         self, fetch):
     # Given
     self.harness.set_leader(True)
     fetch.side_effect = OCIImageResourceError("redis-image")
     # When
     self.harness.charm.on.config_changed.emit()
     # Then
     fetch.assert_called_once_with()
     self.assertEqual(self.harness.charm.unit.status,
                      BlockedStatus("Error fetching image information."))
Exemplo n.º 24
0
    def _install_prometheus_client(self):
        """Install Prometheus tester dependencies."""
        container = self.unit.get_container(self._name)
        if not container.can_connect():
            self.unit.status = BlockedStatus("Waiting for Pebble ready")
            return

        process = container.exec(
            [self._pip_path, "install", "prometheus_client"])
        process.wait()
        logger.debug("Installed prometheus client")
Exemplo n.º 25
0
    def main(self, event):
        self.model.unit.status = MaintenanceStatus("Calculating manifests")
        self.ensure_state()

        try:
            manifest = self.get_manifest()
        except Exception as err:
            self.model.unit.status = BlockedStatus(str(err))
            return

        self.model.unit.status = MaintenanceStatus("Applying manifests")
        errors = self.set_manifest(manifest)

        if errors:
            self.model.unit.status = BlockedStatus(
                f"There were {len(errors)} errors while applying manifests.")
            for error in errors:
                self.logger.error(error)
        else:
            # Ensure requested resources are up
            try:
                for attempt in Retrying(
                        retry=retry_if_exception_type(CheckFailedError),
                        stop=stop_after_delay(
                            max_delay=self._max_time_checking_resources),
                        wait=wait_exponential(multiplier=0.1, min=0.1, max=15),
                        reraise=True,
                ):
                    with attempt:
                        self.logger.info(
                            f"Checking status of requested resources (attempt "
                            f"{attempt.retry_state.attempt_number})")
                        self._check_deployed_resources()
            except CheckFailedError:
                self.unit.status = BlockedStatus(
                    "Some Kubernetes resources did not start correctly during install"
                )
                return

            # Otherwise, application is working as expected
            self.model.unit.status = ActiveStatus()
Exemplo n.º 26
0
 def on_upgrade_charm(self, event):
     if not hasattr(self.state, 'installed'):
         self.on_install(event)
         return
     try:
         check_call(['apt-get', 'update', '-qq'])
         check_call(['apt-get', 'dist-upgrade', '-y'])
         event.framework.model.unit.status = ActiveStatus()
     except Exception as e:
         event.framework.model.unit.status = BlockedStatus('{}: {}'.format(
             "upgrade failed", e))
         event.defer()
Exemplo n.º 27
0
    def test_validate_config_eula_invalid_product_id(self):
        self.harness.update_config({
            'accept-eula': True,
            'product-id': 'Invalid Product ID'
        })

        self.harness.disable_hooks()
        self.harness.begin()

        self.assertFalse(self.harness.charm._validate_config())
        self.assertEqual(self.harness.charm.unit.status,
                         BlockedStatus('Invalid MSSQL product id'))
Exemplo n.º 28
0
    def _on_relation_changed(self, event):
        """Check for slurmdbd and slurmd, write config, set relation data."""
        logger.debug('_on_relation_changed(): entering')

        if len(self.framework.model.relations['slurmd']) > 0:
            if not self._charm.is_slurmd_available():
                self._charm.set_slurmd_available(True)
            self.on.slurmd_available.emit()
        else:
            self._charm.unit.status = BlockedStatus("Need > 0 units of slurmd")
            event.defer()
            return
Exemplo n.º 29
0
    def sanitized_container_config(self):
        """Uninterpolated container config without secrets"""
        config = self.framework.model.config

        if config["container_config"].strip() == "":
            container_config = {}
        else:
            container_config = yaml.safe_load(self.framework.model.config["container_config"])
            if not isinstance(container_config, dict):
                self.framework.model.unit.status = BlockedStatus("container_config is not a YAML mapping")
                return None
        return container_config
Exemplo n.º 30
0
    def configure_pod(self, event):
        # Continue only if the unit is the leader
        if not self.unit.is_leader():
            self.unit.status = ActiveStatus()
            return
        # Check problems in the settings
        problems = self._check_settings()
        if problems:
            self.unit.status = BlockedStatus(problems)
            return

        self.unit.status = BlockedStatus("Assembling pod spec")
        image_details = self._make_pod_image_details()
        ports = self._make_pod_ports()
        env_config = self._make_pod_envconfig()
        command = self._make_pod_command()
        volume_config = self._make_pod_volume_config()
        ingress_resources = self._make_pod_ingress_resources()
        secrets = self._make_pod_secrets()

        pod_spec = {
            "version": 3,
            "containers": [
                {
                    "name": self.framework.model.app.name,
                    "imageDetails": image_details,
                    "ports": ports,
                    "envConfig": env_config,
                    "command": command,
                    "volumeConfig": volume_config,
                }
            ],
            "kubernetesResources": {
                "ingressResources": ingress_resources or [],
                "secrets": secrets,
            },
        }
        self.model.pod.set_spec(pod_spec)
        self.unit.status = ActiveStatus()