Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat(project): add support for docker-cache feature #398

Open
wants to merge 2 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions riocli/apply/manifests/project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: test-project-name
labels:
purpose: testing
version: 1.0
version: "1.0"
spec:
users:
- emailID: "[email protected]"
Expand All @@ -20,4 +20,9 @@ spec:
vpn:
enabled: true
subnets: ["10.81.0.0/16"]

dockerCache:
enabled: true
proxyDevice: "edge01"
proxyInterface: "eth0"
registrySecret: "quay"
registryURL: "https://quay.io"
21 changes: 21 additions & 0 deletions riocli/jsonschema/schemas/project-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@ definitions:
properties:
enabled:
type: boolean
dockerCache:
oneOf:
- properties:
enabled:
const: false
- properties:
enabled:
const: true
proxyDevice:
type: string
proxyInterface:
type: string
registrySecret:
type: string
registryURL:
type: string
required:
- proxyDevice
- proxyInterface
- registrySecret
- registryURL
userGroup:
type: object
properties:
Expand Down
2 changes: 2 additions & 0 deletions riocli/project/features/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from click_help_colors import HelpColorsGroup

from riocli.constants import Colors
from riocli.project.features.dockercache import dockercache
from riocli.project.features.vpn import vpn


Expand All @@ -32,3 +33,4 @@ def features():


features.add_command(vpn)
features.add_command(dockercache)
110 changes: 110 additions & 0 deletions riocli/project/features/dockercache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright 2024 Rapyuta Robotics
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import click
from click_help_colors import HelpColorsCommand

from riocli.config import new_v2_client
from riocli.constants import Colors, Symbols
from riocli.project.util import name_to_guid
from riocli.utils.spinner import with_spinner


@click.command(
"dockercache",
cls=HelpColorsCommand,
help_headers_color=Colors.YELLOW,
help_options_color=Colors.GREEN,
)
@click.argument("project-name", type=str)
@click.argument("enable", type=bool)
@click.option(
"--proxy-device",
type=click.STRING,
default=(),
help="Name of the device for docker-cache proxy.",
)
@click.option(
"--proxy-interface",
type=click.STRING,
default=(),
help="Name of the network interface for docker-cache proxy.",
)
@click.option(
"--registry-url",
type=click.STRING,
default=(),
help="URL for the upstream docker registry.",
)
@click.option(
"--registry-secret",
type=click.STRING,
default=(),
help="Name of the secret for upstream docker registry",
)
@name_to_guid
@with_spinner(text="Updating DockerCache state...")
def dockercache(
project_name: str,
project_guid: str,
enable: bool,
proxy_device: str,
proxy_interface: str,
registry_url: str,
registry_secret: str,
spinner=None,
) -> None:
"""
Enable or disable DockerCache on a project

Example:

\b
rio project features dockercache "my-project" true \\
--proxy-device edge01 \\
--proxy-interface eth0 \\
--registry-url https://quay.io \\
--registry-secret quay
"""
client = new_v2_client(with_project=False)

try:
project = client.get_project(project_guid)
except Exception as e:
spinner.text = click.style("Failed: {}".format(e), fg=Colors.RED)
spinner.red.fail(Symbols.ERROR)
raise SystemExit(1) from e

project["spec"]["features"]["dockerCache"] = {
"enabled": enable,
"proxyDevice": proxy_device,
"proxyInterface": proxy_interface,
"registryURL": registry_url,
"registrySecret": registry_secret,
}

is_enabled = project["spec"]["features"]["dockerCache"].get("enabled", False)

status = "Enabling DockerCache..." if enable else "Disabling DockerCache..."
if is_enabled and enable:
status = "Updating DockerCache..."
spinner.text = status

try:
client.update_project(project_guid, project)
spinner.text = click.style("Done", fg=Colors.GREEN)
spinner.green.ok(Symbols.SUCCESS)
except Exception as e:
spinner.text = click.style("Failed: {}".format(e), fg=Colors.RED)
spinner.red.fail(Symbols.ERROR)
raise SystemExit(1) from e
21 changes: 13 additions & 8 deletions riocli/project/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from riocli.exceptions import ResourceNotFound
from riocli.model import Model
from riocli.project.util import ProjectNotFound, find_project_guid
from riocli.v2client.error import HttpAlreadyExistsError, HttpNotFoundError
from riocli.v2client.error import HttpNotFoundError

PROJECT_READY_TIMEOUT = 150

Expand All @@ -39,19 +39,24 @@ def apply(self, *args, **kwargs) -> ApplyResult:
project["metadata"]["organizationGUID"] = Configuration().organization_guid

try:
client.create_project(project)
# We try to update before creating in Project. The DockerCache
# feature is only available in the Update API. If we instead try to
# create the Project with DockerCache feature enabled then the API
# will return BadRequest error.
guid = find_project_guid(
client, self.metadata.name, Configuration().organization_guid
)

client.update_project(guid, project)
wait(
self.is_ready,
timeout_seconds=PROJECT_READY_TIMEOUT,
sleep_seconds=(1, 30, 2),
)
return ApplyResult.CREATED
except HttpAlreadyExistsError:
guid = find_project_guid(
client, self.metadata.name, Configuration().organization_guid
)
client.update_project(guid, project)
return ApplyResult.UPDATED
except (HttpNotFoundError, ProjectNotFound):
client.create_project(project)
return ApplyResult.CREATED
except Exception as e:
raise e

Expand Down
Loading