Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Fix suggestions from canonical#6

Open
yi-portainer wants to merge 4 commits intomainfrom
fix/suggestions-from-canonical
Open

Fix suggestions from canonical#6
yi-portainer wants to merge 4 commits intomainfrom
fix/suggestions-from-canonical

Conversation

@yi-portainer
Copy link
Contributor

No description provided.

Copy link
Contributor

@jnsgruk jnsgruk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is looking great, thanks @yi-portainer!

A couple of possible improvements:

  • You could steal a Github Actions setup that runs linting and tests from here
  • It might be nice (as indicated by the CI config above) to add a simple integration test that builds and deploys the charm - example here. You may need to do some clever things to deploy the charm using trust (example here)

Comment on lines +1 to +10
[project]
name = "portainer-charm"
description = "Kubernetes charm for Portainer"
license = "Apache 2.0"
python = "^3.8"
readme = "README.md"
homepage = "https://charmhub.io/portainer"
repository = "https://github.com/portainer/portainer-charm"
documentation = "https://charmhub.io/portainer/docs"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be dropped to avoid duplicating data from metadata.yaml that might go out of sync over time :)

Suggested change
[project]
name = "portainer-charm"
description = "Kubernetes charm for Portainer"
license = "Apache 2.0"
python = "^3.8"
readme = "README.md"
homepage = "https://charmhub.io/portainer"
repository = "https://github.com/portainer/portainer-charm"
documentation = "https://charmhub.io/portainer/docs"


# Ignore libraries that do not have type hint nor stubs
[[tool.mypy.overrides]]
module = ["ops.*", "kubernetes.*", "flatten_json.*"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
module = ["ops.*", "kubernetes.*", "flatten_json.*"]
module = ["ops.*", "kubernetes.*"]

I can't see this module actually being used anywhere.

git+https://github.com/canonical/operator/#egg=ops
PyYAML
kubernetes
flatten_json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
flatten_json

I can't see this module actually being used anywhere.

self.unit.status = WaitingStatus('waiting for service account perconditions')
K8sService.create_k8s_service_by_config(self._app_name, self._config)
if not K8sService.create_k8s_service_account(self._app_name):
self.unit.status = WaitingStatus("waiting for service account perconditions")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.unit.status = WaitingStatus("waiting for service account perconditions")
self.unit.status = WaitingStatus("waiting for service account preconditions")

K8sService.create_k8s_service_by_config(self._app_name, self._config)
if not K8sService.create_k8s_service_account(self._app_name):
self.unit.status = WaitingStatus("waiting for service account perconditions")
logger.info("waiting for service account perconditions, installation deferred")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
logger.info("waiting for service account perconditions, installation deferred")
logger.info("waiting for service account preconditions, installation deferred")

@classmethod
def create_k8s_service_by_config(cls, app_name: str, config: PortainerConfig):
"""Delete then create k8s service by stored config."""
api = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as an aside, we've been trialling lightkube in some of our charms. It's a lot simpler than the official kubernetes library, and has better support for newer Kubernetes versions. Specifically, it makes patching things a little easier: example

From my experience so far, it requires fairly minimal rework, and might result in some terser code, but no pressure either way! :)

api = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient())

try:
api.list_namespaced_service(namespace=cls.get_namespace())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may wish to try a more privileged action like listing ClusterRoles or similar to try and get a better picture of whether the charm has sufficient permissions :)

Comment on lines +126 to +147
spec = utils.clean_nones(
client.sanitize_for_serialization(cls.build_k8s_spec_by_config(app_name, config))
)
body = []
for k, v in spec.items():
body.append(
{
"op": "replace",
"path": f"/spec/{k}",
"value": v,
}
)
logger.debug(f"patching with body: {body}")
if body:
api.patch_namespaced_service(
name=app_name,
namespace=cls.get_namespace(),
body=body,
)
else:
logger.info("nothing to patch, skip patching")
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method specifically might be better served with something like the Client.replace method in lightkube

Comment on lines +31 to +33
svc = container.get_services().get(cls.PEBBLE_SERVICE, None)
# Check if the service is already running
if not svc:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
svc = container.get_services().get(cls.PEBBLE_SERVICE, None)
# Check if the service is already running
if not svc:
if not container.get_services().get(cls.PEBBLE_SERVICE, None):

return False

@classmethod
def _build_layer_by_config(cls, config: PortainerConfig) -> dict:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def _build_layer_by_config(cls, config: PortainerConfig) -> dict:
def _pebble_layer(cls, config: PortainerConfig) -> dict:

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants