Skip to content

Commit

Permalink
Merge pull request #996 from alesstimec/remove-dashboard-resource
Browse files Browse the repository at this point in the history
CSS-4739 Removes the dashboard resource.
  • Loading branch information
alesstimec authored Jul 11, 2023
2 parents 842c07a + efe6cce commit 27339bc
Show file tree
Hide file tree
Showing 8 changed files with 5 additions and 457 deletions.
4 changes: 0 additions & 4 deletions charms/jimm-k8s/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ containers:
resource: jimm-image

resources:
dashboard:
type: file
filename: dashboard.tar.xz
description: "juju dashboard tarball."
jimm-image:
type: oci-image
description: OCI image for JIMM.
Expand Down
95 changes: 1 addition & 94 deletions charms/jimm-k8s/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import hashlib
import json
import logging
import os
import socket

import hvac
Expand All @@ -43,16 +42,9 @@
IngressPerAppRequirer,
IngressPerAppRevokedEvent,
)
from ops import pebble
from ops.charm import CharmBase, RelationJoinedEvent
from ops.main import main
from ops.model import (
ActiveStatus,
BlockedStatus,
MaintenanceStatus,
ModelError,
WaitingStatus,
)
from ops.model import ActiveStatus, BlockedStatus, WaitingStatus

from state import State, requires_state, requires_state_setter

Expand Down Expand Up @@ -167,8 +159,6 @@ def __init__(self, *args):
self._agent_filename = "/root/config/agent.json"
self._vault_secret_filename = "/root/config/vault_secret.json"
self._vault_path = "charm-jimm-k8s-creds"
self._dashboard_path = "/root/dashboard"
self._dashboard_hash_path = "/root/dashboard/hash"

def _on_peer_relation_changed(self, event):
self._update_workload(event)
Expand Down Expand Up @@ -217,7 +207,6 @@ def _update_workload(self, event):

self._ensure_bakery_agent_file(event)
self._ensure_vault_file(event)
self._install_dashboard(event)

dns_name = self._get_dns_name(event)
if not dns_name:
Expand Down Expand Up @@ -249,9 +238,6 @@ def _update_workload(self, event):
if self.model.unit.is_leader():
config_values["JIMM_WATCH_CONTROLLERS"] = "1"

if container.exists(self._dashboard_path):
config_values["JIMM_DASHBOARD_LOCATION"] = self._dashboard_path

# remove empty configuration values
config_values = {key: value for key, value in config_values.items() if value}

Expand Down Expand Up @@ -382,85 +368,6 @@ def _ready(self):
self.unit.status = WaitingStatus("waiting for jimm workload")
return False

def _install_dashboard(self, event):
container = self.unit.get_container(WORKLOAD_CONTAINER)

# if we can't connect to the container we should defer
# this event.
if not container.can_connect():
event.defer()
return

# fetch the resource filename
try:
dashboard_file = self.model.resources.fetch("dashboard")
except ModelError:
dashboard_file = None

# if the resource is not specified, we can return
# as there is nothing to install.
if not dashboard_file:
return

# if the resource file is empty, we can return
# as there is nothing to install.
if os.path.getsize(dashboard_file) == 0:
return

dashboard_changed = False

# compute the hash of the dashboard tarball.
dashboard_hash = self._hash(dashboard_file)

# check if we the file containing the dashboard
# hash exists.
if container.exists(self._dashboard_hash_path):
# if it does, compare the stored hash with the
# hash of the dashboard tarball.
hash = container.pull(self._dashboard_hash_path)
existing_hash = str(hash.read())
# if the two hashes do not match
# the resource must have changed.
if not dashboard_hash == existing_hash:
dashboard_changed = True
else:
dashboard_changed = True

# if the resource file has not changed, we can
# return as there is no need to push the same
# dashboard content to the container.
if not dashboard_changed:
return

self.unit.status = MaintenanceStatus("installing dashboard")

# remove the existing dashboard from the workload/
if container.exists(self._dashboard_path):
container.remove_path(self._dashboard_path, recursive=True)

container.make_dir(self._dashboard_path, make_parents=True)

with open(dashboard_file, "rb") as f:
container.push(os.path.join(self._dashboard_path, "dashboard.tar.bz2"), f)

process = container.exec(
[
"tar",
"xvf",
os.path.join(self._dashboard_path, "dashboard.tar.bz2"),
"-C",
self._dashboard_path,
]
)
try:
process.wait_output()
except pebble.ExecError as e:
logger.error("error running untaring the dashboard. error code {}".format(e.exit_code))
for line in e.stderr.splitlines():
logger.error(" %s", line)

self._push_to_workload(self._dashboard_hash_path, dashboard_hash, event)

def _get_network_address(self, event):
return str(self.model.get_binding(event.relation).network.egress_subnets[0].network_address)

Expand Down
58 changes: 0 additions & 58 deletions charms/jimm-k8s/tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
# Learn more about testing at: https://juju.is/docs/sdk/testing


import io
import json
import pathlib
import tarfile
import tempfile
import unittest
from unittest.mock import patch
Expand Down Expand Up @@ -172,62 +170,6 @@ def test_bakery_configuration(self):
},
)

@patch("ops.model.Container.exec")
def test_install_dashboard(self, exec):
exec.unwrap.return_value = MockExec()

container = self.harness.model.unit.get_container("jimm")

self.harness.add_resource("dashboard", self.dashboard_tarfile())

self.harness.update_config(MINIMAL_CONFIG)
self.harness.charm.on.jimm_pebble_ready.emit(container)

plan = self.harness.get_container_pebble_plan("jimm")
self.assertEqual(
plan.to_dict(),
{
"services": {
"jimm": {
"summary": "JAAS Intelligent Model Manager",
"startup": "disabled",
"override": "merge",
"command": "/root/jimmsrv",
"environment": {
"CANDID_URL": "test-candid-url",
"JIMM_LISTEN_ADDR": ":8080",
"JIMM_DASHBOARD_LOCATION": "/root/dashboard",
"JIMM_DNS_NAME": "juju-jimm-k8s-0.juju-jimm-k8s-endpoints.None.svc.cluster.local",
"JIMM_LOG_LEVEL": "info",
"JIMM_UUID": "1234567890",
"JIMM_WATCH_CONTROLLERS": "1",
},
}
}
},
)

self.assertEqual(container.exists("/root/dashboard"), True)
self.assertEqual(container.isdir("/root/dashboard"), True)
self.assertEqual(container.exists("/root/dashboard/dashboard.tar.bz2"), True)
self.assertEqual(container.exists("/root/dashboard/hash"), True)

def dashboard_tarfile(self):
dashboard_archive = io.BytesIO()

data = bytes("Hello world", "utf-8")
f = io.BytesIO(initial_bytes=data)
with tarfile.open(fileobj=dashboard_archive, mode="w:bz2") as tar:
info = tarfile.TarInfo("README.md")
info.size = len(data)
tar.addfile(info, f)
tar.close()

dashboard_archive.flush()
dashboard_archive.seek(0)
data = dashboard_archive.read()
return data

def test_dashboard_relation_joined(self):
harness = Harness(JimmOperatorCharm)
self.addCleanup(harness.cleanup)
Expand Down
4 changes: 0 additions & 4 deletions charms/jimm/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,3 @@ resources:
type: file
filename: jimm.snap
description: Snap containing the JIMM server.
dashboard:
type: file
filename: dashboard.tar.bz2
description: "Tarball containing the Juju Dashboard."
40 changes: 0 additions & 40 deletions charms/jimm/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import shutil
import socket
import subprocess
import tarfile
import urllib

import hvac
Expand Down Expand Up @@ -60,7 +59,6 @@ def __init__(self, *args):
self._agent_filename = "/var/snap/jimm/common/agent.json"
self._vault_secret_filename = "/var/snap/jimm/common/vault_secret.json"
self._workload_filename = "/snap/bin/jimm"
self._dashboard_path = "/var/snap/jimm/common/dashboard"
self._rsyslog_conf_path = "/etc/rsyslog.d/10-jimm.conf"
self._logrotate_conf_path = "/etc/logrotate.d/jimm"

Expand Down Expand Up @@ -93,7 +91,6 @@ def _on_install(self, _):
"""Install the JIMM software."""
self._write_service_file()
self._install_snap()
self._install_dashboard()
self._setup_logging()
self._on_update_status(None)

Expand All @@ -108,7 +105,6 @@ def _on_upgrade_charm(self, _):
"""Upgrade the charm software."""
self._write_service_file()
self._install_snap()
self._install_dashboard()
self._setup_logging()
if self._ready():
self.restart()
Expand All @@ -127,8 +123,6 @@ def _on_config_changed(self, _):
"uuid": self.config.get("uuid"),
"dashboard_location": self.config.get("juju-dashboard-location"),
}
if os.path.exists(self._dashboard_path):
args["dashboard_location"] = self._dashboard_path

with open(self._env_filename(), "wt") as f:
f.write(self._render_template("jimm.env", **args))
Expand Down Expand Up @@ -283,34 +277,6 @@ def _install_snap(self):
return
self._snap("install", "--dangerous", path)

def _install_dashboard(self):
try:
path = self.model.resources.fetch("dashboard")
except ModelError:
path = None

if not path:
return

if self._dashboard_resource_nonempty():
new_dashboard_path = self._dashboard_path + ".new"
old_dashboard_path = self._dashboard_path + ".old"
shutil.rmtree(new_dashboard_path, ignore_errors=True)
shutil.rmtree(old_dashboard_path, ignore_errors=True)
os.mkdir(new_dashboard_path)

self.unit.status = MaintenanceStatus("installing dashboard")
with tarfile.open(path, mode="r:bz2") as tf:
tf.extractall(new_dashboard_path)

# Change the owner/group of all extracted files to root/wheel.
for name in tf.getnames():
os.chown(os.path.join(new_dashboard_path, name), 0, 0)

if os.path.exists(self._dashboard_path):
os.rename(self._dashboard_path, old_dashboard_path)
os.rename(new_dashboard_path, self._dashboard_path)

def _setup_logging(self):
"""Install the logging configuration."""
shutil.copy(
Expand All @@ -323,12 +289,6 @@ def _setup_logging(self):
)
self._systemctl("restart", "rsyslog")

def _dashboard_resource_nonempty(self):
dashboard_file = self.model.resources.fetch("dashboard")
if dashboard_file:
return os.path.getsize(dashboard_file) != 0
return False

def _bakery_agent_file(self):
url = self.config.get("candid-url", "")
username = self.config.get("candid-agent-username", "")
Expand Down
Loading

0 comments on commit 27339bc

Please sign in to comment.