diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4d24934 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__ +.tox +*.rock +venv diff --git a/notebook-controller/rockcraft.yaml b/notebook-controller/rockcraft.yaml index 2489452..7d3975c 100644 --- a/notebook-controller/rockcraft.yaml +++ b/notebook-controller/rockcraft.yaml @@ -1,11 +1,12 @@ +# Source https://github.com/kubeflow/kubeflow/blob/v1.9.0-rc.0/components/notebook-controller/Dockerfile name: notebook-controller summary: An image for Jupyter notebook controller description: | This image is used as part of the Charmed Kubeflow product. The controller allows users to create a custom resource "Notebook" (jupyter notebook). -version: v1.8.0_22.04_1 # version format: __ +version: "1.9.0" license: Apache-2.0 -base: ubuntu:22.04 +base: ubuntu@22.04 services: jupyter-controller: override: replace @@ -17,13 +18,21 @@ platforms: amd64: parts: + security-team-requirement: + plugin: nil + override-build: | + mkdir -p ${CRAFT_PART_INSTALL}/usr/share/rocks + (echo "# os-release" && cat /etc/os-release && echo "# dpkg-query" && \ + dpkg-query -f '${db:Status-Abbrev},${binary:Package},${Version},${source:Package},${Source:Version}\n' -W) > \ + ${CRAFT_PART_INSTALL}/usr/share/rocks/dpkg.query + notebook-controller: plugin: go source: https://github.com/kubeflow/kubeflow source-type: git - source-tag: v1.8-branch # upstream branch + source-tag: v1.9.0-rc.0 build-snaps: - - go + - go/1.17/stable build-packages: - apt - bash @@ -49,12 +58,6 @@ parts: cp third_party/license.txt $CRAFT_PART_INSTALL/third_party/license.txt cp -r /root/go/pkg/mod/github.com/hashicorp $CRAFT_PART_INSTALL/third_party/hashicorp - # security requirement - mkdir -p ${CRAFT_PART_INSTALL}/usr/share/rocks - (echo "# os-release" && cat /etc/os-release && echo "# dpkg-query" && \ - dpkg-query -f '${db:Status-Abbrev},${binary:Package},${Version},${source:Package},${Source:Version}\n' -W) \ - > ${CRAFT_PART_INSTALL}/usr/share/rocks/dpkg.query - non-root-user: plugin: nil after: [notebook-controller] diff --git a/notebook-controller/tests/test_rock.py b/notebook-controller/tests/test_rock.py new file mode 100644 index 0000000..83fec2d --- /dev/null +++ b/notebook-controller/tests/test_rock.py @@ -0,0 +1,69 @@ +# Copyright 2024 Canonical Ltd. +# See LICENSE file for licensing details. +# +# + +from pathlib import Path + +import os +import logging +import random +import pytest +import string +import subprocess +import yaml + +from charmed_kubeflow_chisme.rock import CheckRock + + +@pytest.fixture() +def rock_test_env(tmpdir): + """Yields a temporary directory and random docker container name, then cleans them up after.""" + container_name = "".join( + [str(i) for i in random.choices(string.ascii_lowercase, k=8)] + ) + yield tmpdir, container_name + + try: + subprocess.run(["docker", "rm", container_name]) + except Exception: + pass + # tmpdir fixture we use here should clean up the other files for us + + +@pytest.mark.abort_on_fail +def test_rock(rock_test_env): + """Test rock.""" + temp_dir, container_name = rock_test_env + check_rock = CheckRock("rockcraft.yaml") + rock_image = check_rock.get_name() + rock_version = check_rock.get_version() + LOCAL_ROCK_IMAGE = f"{rock_image}:{rock_version}" + + subprocess.run( + [ + "docker", + "run", + "--rm", + LOCAL_ROCK_IMAGE, + "exec", + "ls", + "-la", + "/manager", + ], + check=True, + ) + + subprocess.run( + [ + "docker", + "run", + "--rm", + LOCAL_ROCK_IMAGE, + "exec", + "ls", + "-la", + "/third_party/hashicorp", + ], + check=True, + ) diff --git a/notebook-controller/tox.ini b/notebook-controller/tox.ini index 565496c..bb38d9d 100644 --- a/notebook-controller/tox.ini +++ b/notebook-controller/tox.ini @@ -1,8 +1,9 @@ -# Copyright 2023 Canonical Ltd. +# Copyright 2024 Canonical Ltd. # See LICENSE file for licensing details. [tox] skipsdist = True skip_missing_interpreters = True +envlist = pack, export-to-docker, sanity, integration [testenv] setenv = @@ -12,34 +13,42 @@ setenv = CHARM_BRANCH=main LOCAL_CHARM_DIR=charm_repo - -[testenv:integration] +[testenv:pack] passenv = * allowlist_externals = - bash - git - rm - tox rockcraft -deps = - juju<4.0 - pytest - pytest-operator - ops commands = - # build and pack rock rockcraft pack - # clone related charm - rm -rf {env:LOCAL_CHARM_DIR} - git clone --branch {env:CHARM_BRANCH} {env:CHARM_REPO} {env:LOCAL_CHARM_DIR} - # upload rock to docker and microk8s cache, replace charm's container with local rock reference + +[testenv:export-to-docker] +passenv = * +allowlist_externals = + bash + skopeo + yq +commands = + # export rock to docker bash -c 'NAME=$(yq eval .name rockcraft.yaml) && \ VERSION=$(yq eval .version rockcraft.yaml) && \ - ARCH=$(yq eval -r ".platforms | keys" rockcraft.yaml | cut -d" " -f2) && \ - ROCK="$\{NAME\}_$\{VERSION\}_$\{ARCH\}" && \ - sudo /snap/rockcraft/current/bin/skopeo --insecure-policy copy oci-archive:$ROCK.rock docker-daemon:$ROCK:$VERSION && \ - docker save $ROCK > $ROCK.tar && \ - microk8s ctr image import $ROCK.tar && \ - yq e -i ".resources.oci-image.upstream-source=\"$ROCK:$VERSION\"" {env:LOCAL_CHARM_DIR}/charms/jupyter-controller/metadata.yaml' - # run charm integration test with rock - tox -c {env:LOCAL_CHARM_DIR} -e controller-integration \ No newline at end of file + ARCH=$(yq eval ".platforms | keys | .[0]" rockcraft.yaml) && \ + ROCK="$\{NAME\}_$\{VERSION\}_$\{ARCH\}.rock" && \ + DOCKER_IMAGE=$NAME:$VERSION && \ + echo "Exporting $ROCK to docker as $DOCKER_IMAGE" && \ + skopeo --insecure-policy copy oci-archive:$ROCK docker-daemon:$DOCKER_IMAGE' + +[testenv:sanity] +passenv = * +deps = + pytest + charmed-kubeflow-chisme +commands = + # run rock tests + pytest -s -v --tb native --show-capture=all --log-cli-level=INFO {posargs} {toxinidir}/tests + +[testenv:integration] +passenv = * +allowlist_externals = + echo +commands = + # TODO: Implement integration tests here + echo "WARNING: This is a placeholder test - no test is implemented here."