Implement openstack-images-sync on k8s
Change-Id: Ie9a6559762a1180657f06307674daf4eba559a0f
This commit is contained in:
parent
52706b1332
commit
f0adcefc64
34
charms/openstack-images-sync-k8s/CONTRIBUTING.md
Normal file
34
charms/openstack-images-sync-k8s/CONTRIBUTING.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Contributing
|
||||
|
||||
To make contributions to this charm, you'll need a working [development setup](https://juju.is/docs/sdk/dev-setup).
|
||||
|
||||
You can create an environment for development with `tox`:
|
||||
|
||||
```shell
|
||||
tox devenv -e integration
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
This project uses `tox` for managing test environments. There are some pre-configured environments
|
||||
that can be used for linting and formatting code when you're preparing contributions to the charm:
|
||||
|
||||
```shell
|
||||
tox run -e format # update your code according to linting rules
|
||||
tox run -e lint # code style
|
||||
tox run -e static # static type checking
|
||||
tox run -e unit # unit tests
|
||||
tox run -e integration # integration tests
|
||||
tox # runs 'format', 'lint', 'static', and 'unit' environments
|
||||
```
|
||||
|
||||
## Build the charm
|
||||
|
||||
Build the charm in this git repository using:
|
||||
|
||||
```shell
|
||||
charmcraft pack
|
||||
```
|
||||
|
||||
<!-- You may want to include any contribution/style guidelines in this document>
|
202
charms/openstack-images-sync-k8s/LICENSE
Normal file
202
charms/openstack-images-sync-k8s/LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2024 Canonical Ltd.
|
||||
|
||||
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.
|
66
charms/openstack-images-sync-k8s/README.md
Normal file
66
charms/openstack-images-sync-k8s/README.md
Normal file
@ -0,0 +1,66 @@
|
||||
# openstack-images-sync-k8s
|
||||
|
||||
## Description
|
||||
|
||||
openstack-images-sync-k8s is an operator to manage openstack images sync on a Kubernetes based environment.
|
||||
Openstack Images Sync is a tool to sync images from a Simplestreams source to an Openstack cloud.
|
||||
|
||||
## Usage
|
||||
|
||||
### Deployment
|
||||
|
||||
openstack-images-sync-k8s is deployed using below command:
|
||||
|
||||
juju deploy openstack-images-sync-k8s openstack-images-sync
|
||||
|
||||
Now connect the openstack images sync operator to existing ingress,
|
||||
and keystone identity operators:
|
||||
|
||||
juju relate keystone:identity-service openstack-images-sync:identity-service
|
||||
juju relate traefik-public:ingress openstack-images-sync:ingress-public
|
||||
juju relate traefik-internal:ingress openstack-images-sync:ingress-internal
|
||||
|
||||
### Configuration
|
||||
|
||||
This section covers common and/or important configuration options. See file
|
||||
`charmcraft.yaml` for the full list of options, along with their descriptions and
|
||||
default values. See the [Juju documentation][juju-docs-config-apps] for details
|
||||
on configuring applications.
|
||||
|
||||
### Actions
|
||||
|
||||
This section covers Juju [actions][juju-docs-actions] supported by the charm.
|
||||
Actions allow specific operations to be performed on a per-unit basis. To
|
||||
display action descriptions run `juju actions openstack-images-sync`. If the charm is not
|
||||
deployed then see file `charmcraft.yaml`.
|
||||
|
||||
## Relations
|
||||
|
||||
openstack-images-sync-k8s requires the following relations:
|
||||
|
||||
`identity-service`: To register endpoints in Keystone
|
||||
`ingress-internal`: To expose service on underlying internal network
|
||||
`ingress-public`: To expose service on public network
|
||||
|
||||
## OCI Images
|
||||
|
||||
The charm by default uses following images:
|
||||
|
||||
`ghcr.io/canonical/openstack-images-sync:2024.1`
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see the [Juju SDK docs](https://juju.is/docs/sdk) for guidelines
|
||||
on enhancements to this charm following best practice guidelines, and
|
||||
[CONTRIBUTING.md](contributors-guide) for developer guidance.
|
||||
|
||||
## Bugs
|
||||
|
||||
Please report bugs on [Launchpad][lp-bugs-charm-ois-k8s].
|
||||
|
||||
<!-- LINKS -->
|
||||
|
||||
[contributors-guide]: https://opendev.org/openstack/sunbeam-charms/src/branch/main/charms/openstack-images-sync-k8s/CONTRIBUTING.md
|
||||
[juju-docs-actions]: https://jaas.ai/docs/actions
|
||||
[juju-docs-config-apps]: https://juju.is/docs/configuring-applications
|
||||
[lp-bugs-charm-ois-k8s]: https://bugs.launchpad.net/sunbeam-charms/+filebug
|
93
charms/openstack-images-sync-k8s/charmcraft.yaml
Normal file
93
charms/openstack-images-sync-k8s/charmcraft.yaml
Normal file
@ -0,0 +1,93 @@
|
||||
name: openstack-images-sync-k8s
|
||||
|
||||
type: charm
|
||||
|
||||
title: OpenStack Images Sync K8S
|
||||
|
||||
summary: Keep OpenStack images in sync with the latest versions
|
||||
|
||||
description: |
|
||||
Openstack Images Sync operator allows synchronization from a SimpleStreams source to an OpenStack cloud.
|
||||
|
||||
bases:
|
||||
- build-on:
|
||||
- name: ubuntu
|
||||
channel: "22.04"
|
||||
run-on:
|
||||
- name: ubuntu
|
||||
channel: "22.04"
|
||||
|
||||
config:
|
||||
options:
|
||||
debug:
|
||||
default: False
|
||||
type: boolean
|
||||
frequency:
|
||||
default: hourly
|
||||
description: |
|
||||
The frequency at which the charm should check for new images.
|
||||
Valid values are hourly, daily, weekly.
|
||||
type: string
|
||||
architecture:
|
||||
default: amd64
|
||||
description: |
|
||||
The architectures to sync images for. Space delimited list of architectures.
|
||||
type: string
|
||||
release:
|
||||
default: focal jammy
|
||||
description: |
|
||||
The releases to sync images for. Space delimited list of releases.
|
||||
type: string
|
||||
cloud-name:
|
||||
default: simplestreams-glance-sync
|
||||
description: |
|
||||
The name of the cloud to sync images for.
|
||||
type: string
|
||||
max-items:
|
||||
default: 1
|
||||
description: |
|
||||
The maximum number of images to keep in sync per version.
|
||||
type: int
|
||||
os-admin-hostname:
|
||||
default: openstack-images-sync.juju
|
||||
description: |
|
||||
The hostname or address of the admin endpoints that should be advertised
|
||||
in the openstack image sync.
|
||||
type: string
|
||||
os-internal-hostname:
|
||||
default: openstack-images-sync.juju
|
||||
description: |
|
||||
The hostname or address of the internal endpoints that should be advertised
|
||||
in the openstack image sync.
|
||||
type: string
|
||||
os-public-hostname:
|
||||
default: openstack-images-sync.juju
|
||||
description: |
|
||||
The hostname or address of the internal endpoints that should be advertised
|
||||
in the openstack image sync.
|
||||
type: string
|
||||
region:
|
||||
default: RegionOne
|
||||
description: Space delimited list of OpenStack regions
|
||||
type: string
|
||||
|
||||
containers:
|
||||
openstack-images-sync:
|
||||
resource: openstack-images-sync-image
|
||||
|
||||
resources:
|
||||
openstack-images-sync-image:
|
||||
type: oci-image
|
||||
description: OCI image for OpenStack Images Sync
|
||||
upstream-source: ghcr.io/canonical/openstack-images-sync:2024.1
|
||||
|
||||
requires:
|
||||
ingress-internal:
|
||||
interface: ingress
|
||||
limit: 1
|
||||
optional: true
|
||||
ingress-public:
|
||||
interface: ingress
|
||||
limit: 1
|
||||
identity-service:
|
||||
interface: keystone
|
3
charms/openstack-images-sync-k8s/rebuild
Normal file
3
charms/openstack-images-sync-k8s/rebuild
Normal file
@ -0,0 +1,3 @@
|
||||
# This file is used to trigger a build.
|
||||
# Change uuid to trigger a new build.
|
||||
886a46db-8f02-4271-a825-91153f83c579
|
6
charms/openstack-images-sync-k8s/requirements.txt
Normal file
6
charms/openstack-images-sync-k8s/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
ops
|
||||
jinja2
|
||||
lightkube
|
||||
lightkube-models
|
||||
|
||||
tenacity
|
267
charms/openstack-images-sync-k8s/src/charm.py
Executable file
267
charms/openstack-images-sync-k8s/src/charm.py
Executable file
@ -0,0 +1,267 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Copyright 2024 Canonical Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Openstack Images Sync Operator.
|
||||
|
||||
This charm deploys the openstack images sync service on Kubernetes.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
)
|
||||
|
||||
import ops
|
||||
import ops_sunbeam.charm as sunbeam_charm
|
||||
import ops_sunbeam.config_contexts as sunbeam_config_contexts
|
||||
import ops_sunbeam.container_handlers as sunbeam_chandlers
|
||||
import ops_sunbeam.core as sunbeam_core
|
||||
from charms.keystone_k8s.v1.identity_service import (
|
||||
IdentityServiceRequires,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _frequency_to_seconds(frequency: str) -> int:
|
||||
"""Convert given frequency word to seconds.
|
||||
|
||||
test-do-not-use is for testing purposes only.
|
||||
"""
|
||||
match frequency:
|
||||
case "hourly":
|
||||
return 3600
|
||||
case "daily":
|
||||
return 86400
|
||||
case "weekly":
|
||||
return 604800
|
||||
case "test-do-not-use":
|
||||
return 30
|
||||
case _:
|
||||
raise ValueError(f"Unknown frequency {frequency!r}")
|
||||
|
||||
|
||||
class SyncCharmConfigContext(sunbeam_config_contexts.CharmConfigContext):
|
||||
"""Configure context for templates."""
|
||||
|
||||
def context(self) -> dict:
|
||||
"""Return context for template rendering."""
|
||||
return {
|
||||
**self.charm.config,
|
||||
"architecture": "|".join(
|
||||
self.charm.config["architecture"].split()
|
||||
),
|
||||
"release": "|".join(self.charm.config["release"].split()),
|
||||
"region": ", ".join(self.charm.config["region"].split()),
|
||||
"frequency": _frequency_to_seconds(self.charm.config["frequency"]),
|
||||
}
|
||||
|
||||
|
||||
class HttpSyncConfigContext(sunbeam_config_contexts.ConfigContext):
|
||||
"""Configuration context for the http sync service."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
charm: "OpenstackImagesSyncK8SCharm"
|
||||
|
||||
def context(self) -> dict:
|
||||
"""Httpd configuration options."""
|
||||
return {
|
||||
"name": self.charm.service_name,
|
||||
"public_port": self.charm.default_public_ingress_port,
|
||||
"error_log": "/dev/stdout",
|
||||
"custom_log": "/dev/stdout",
|
||||
}
|
||||
|
||||
|
||||
class OpenstackImagesSyncPebbleHandler(sunbeam_chandlers.ServicePebbleHandler):
|
||||
"""Handler for openstack images sync container."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
charm: "OpenstackImagesSyncK8SCharm"
|
||||
|
||||
@property
|
||||
def directories(self) -> list[sunbeam_chandlers.ContainerDir]:
|
||||
"""List of directories to create in container."""
|
||||
return [
|
||||
sunbeam_chandlers.ContainerDir(
|
||||
"/var/www/html/simplestreams",
|
||||
self.charm.service_user,
|
||||
self.charm.service_group,
|
||||
),
|
||||
]
|
||||
|
||||
def get_layer(self) -> dict:
|
||||
"""Openstack Images Sync service pebble layer.
|
||||
|
||||
:returns: pebble layer configuration for openstack images sync service
|
||||
"""
|
||||
return {
|
||||
"summary": f"{self.service_name} layer",
|
||||
"description": f"pebble config layer for {self.service_name}",
|
||||
"services": {
|
||||
"images-sync": {
|
||||
"override": "replace",
|
||||
"summary": self.service_name,
|
||||
"command": (
|
||||
"/usr/bin/openstack-images-sync sync"
|
||||
" --config /etc/openstack-images-sync/config.yaml"
|
||||
),
|
||||
"user": "_daemon_",
|
||||
"group": "_daemon_",
|
||||
"environment": {
|
||||
**self.charm.keystone_auth(),
|
||||
**self.charm.proxy_env(),
|
||||
},
|
||||
},
|
||||
"http-mirror": {
|
||||
"override": "replace",
|
||||
"summary": "apache",
|
||||
"command": "/usr/sbin/apache2ctl -DFOREGROUND",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def init_service(self, context: sunbeam_core.OPSCharmContexts) -> None:
|
||||
"""Initialise service ready for use.
|
||||
|
||||
Write configuration files to the container and record
|
||||
that service is ready for us. Enable apache modules.
|
||||
"""
|
||||
self.execute(["a2dissite", "000-default"], exception_on_error=True)
|
||||
return super().init_service(context)
|
||||
|
||||
|
||||
class OpenstackImagesSyncK8SCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
"""Charm the application."""
|
||||
|
||||
service_name = "openstack-images-sync"
|
||||
mandatory_relations = {
|
||||
"identity-service",
|
||||
"ingress-public",
|
||||
}
|
||||
|
||||
@property
|
||||
def service_conf(self) -> str:
|
||||
"""Service default configuration file."""
|
||||
return "/etc/openstack-images-sync/config.yaml"
|
||||
|
||||
@property
|
||||
def service_user(self) -> str:
|
||||
"""Service user file and directory ownership."""
|
||||
return "_daemon_"
|
||||
|
||||
@property
|
||||
def service_group(self) -> str:
|
||||
"""Service group file and directory ownership."""
|
||||
return "_daemon_"
|
||||
|
||||
@property
|
||||
def default_public_ingress_port(self) -> int:
|
||||
"""Default ingress port."""
|
||||
return 80
|
||||
|
||||
@property
|
||||
def service_endpoints(self):
|
||||
"""Describe the openstack images sync service endpoint."""
|
||||
slash_region = "/" + self.config["region"].split()[0]
|
||||
return [
|
||||
{
|
||||
"service_name": "image-stream",
|
||||
"type": "product-streams",
|
||||
"description": "Image stream service",
|
||||
"internal_url": self.internal_url + slash_region,
|
||||
"public_url": self.public_url + slash_region,
|
||||
"admin_url": self.admin_url + slash_region,
|
||||
}
|
||||
]
|
||||
|
||||
@property
|
||||
def config_contexts(self) -> list[sunbeam_config_contexts.ConfigContext]:
|
||||
"""Generate list of configuration adapters for the charm."""
|
||||
return [
|
||||
SyncCharmConfigContext(self, "options"),
|
||||
# don't use wsgi-context here
|
||||
HttpSyncConfigContext(self, "httpd_config"),
|
||||
]
|
||||
|
||||
def get_pebble_handlers(self) -> list[sunbeam_chandlers.PebbleHandler]:
|
||||
"""Pebble handlers for the service."""
|
||||
return [
|
||||
OpenstackImagesSyncPebbleHandler(
|
||||
self,
|
||||
self.service_name,
|
||||
self.service_name,
|
||||
self.container_configs,
|
||||
self.template_dir,
|
||||
self.configure_charm,
|
||||
)
|
||||
]
|
||||
|
||||
@property
|
||||
def container_configs(self) -> list[sunbeam_core.ContainerConfigFile]:
|
||||
"""Container configurations for the operator."""
|
||||
_cconfigs = [
|
||||
sunbeam_core.ContainerConfigFile(
|
||||
self.service_conf,
|
||||
self.service_user,
|
||||
self.service_group,
|
||||
0o640,
|
||||
),
|
||||
sunbeam_core.ContainerConfigFile(
|
||||
"/etc/apache2/sites-enabled/http-sync.conf",
|
||||
"root",
|
||||
"root",
|
||||
0o640,
|
||||
),
|
||||
]
|
||||
return _cconfigs
|
||||
|
||||
def keystone_auth(self) -> dict[str, str]:
|
||||
"""Keystone authentication."""
|
||||
if self.id_svc.ready:
|
||||
interface: IdentityServiceRequires = self.id_svc.interface # type: ignore
|
||||
return {
|
||||
# Using public auth url because openstack-images-sync will output an index.json
|
||||
# referencing this auth url. Later on, client will want to match the clouds and
|
||||
# will use a combo of auth_url + region.
|
||||
"OS_AUTH_URL": interface.public_auth_url,
|
||||
"OS_IDENTITY_API_VERSION": "3",
|
||||
"OS_USERNAME": interface.service_user_name,
|
||||
"OS_PASSWORD": interface.service_password,
|
||||
"OS_PROJECT_NAME": interface.service_project_name,
|
||||
"OS_USER_DOMAIN_NAME": interface.service_domain_name,
|
||||
"OS_PROJECT_DOMAIN_NAME": interface.service_domain_name,
|
||||
}
|
||||
return {}
|
||||
|
||||
def proxy_env(self) -> dict[str, str]:
|
||||
"""Get proxy settings from environment."""
|
||||
juju_proxy_vars = [
|
||||
"JUJU_CHARM_HTTP_PROXY",
|
||||
"JUJU_CHARM_HTTPS_PROXY",
|
||||
"JUJU_CHARM_NO_PROXY",
|
||||
]
|
||||
return {
|
||||
proxy_var.removeprefix("JUJU_CHARM_"): value
|
||||
for proxy_var in juju_proxy_vars
|
||||
if (value := os.environ.get(proxy_var))
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: nocover
|
||||
ops.main(OpenstackImagesSyncK8SCharm) # type: ignore
|
@ -0,0 +1,20 @@
|
||||
cloud_name: {{ options.cloud_name}}
|
||||
frequency: {{ options.frequency }}
|
||||
mirrors:
|
||||
- content_id: '%(region)s' # Content ID choice
|
||||
custom_properties: {}
|
||||
hypervisor_mapping: false
|
||||
image_conversion: false
|
||||
item_filters:
|
||||
- release~({{ options.release }})
|
||||
- arch~({{ options.architecture }})
|
||||
- ftype~(disk1.img|disk.img)
|
||||
keep_items: false
|
||||
latest_property: false
|
||||
max_items: {{ options.max_items }}
|
||||
url: http://cloud-images.ubuntu.com/releases
|
||||
path: streams/v1/index.sjson
|
||||
regions: [{{ options.region }}]
|
||||
visibility: public
|
||||
name_prefix: auto-sync/
|
||||
output_directory: /var/www/html/simplestreams
|
@ -0,0 +1,18 @@
|
||||
Listen {{ httpd_config.public_port }}
|
||||
|
||||
<VirtualHost *:{{ httpd_config.public_port }}>
|
||||
DocumentRoot "/var/www/html/simplestreams"
|
||||
|
||||
{% if ingress_public and ingress_public.ingress_path %}
|
||||
Alias {{ ingress_public.ingress_path }} "/var/www/html/simplestreams"
|
||||
{% endif %}
|
||||
|
||||
<Directory "/var/www/html/simplestreams">
|
||||
Options Indexes
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog {{ httpd_config.error_log }}
|
||||
CustomLog {{ httpd_config.custom_log }} combined
|
||||
</VirtualHost>
|
15
charms/openstack-images-sync-k8s/tests/unit/__init__.py
Normal file
15
charms/openstack-images-sync-k8s/tests/unit/__init__.py
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright 2024 Canonical Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Unit tests for charm."""
|
125
charms/openstack-images-sync-k8s/tests/unit/test_charm.py
Normal file
125
charms/openstack-images-sync-k8s/tests/unit/test_charm.py
Normal file
@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2024 Canonical Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Tests for openstack images sync charm."""
|
||||
import pathlib
|
||||
|
||||
import charm
|
||||
import ops_sunbeam.test_utils as test_utils
|
||||
import yaml
|
||||
|
||||
charmcraft = (
|
||||
pathlib.Path(__file__).parents[2] / "charmcraft.yaml"
|
||||
).read_text()
|
||||
config = yaml.dump(yaml.safe_load(charmcraft)["config"])
|
||||
|
||||
|
||||
class _OISOperatorCharm(charm.OpenstackImagesSyncK8SCharm):
|
||||
"""Openstack Images Sync test charm."""
|
||||
|
||||
def __init__(self, framework):
|
||||
"""Setup event logging."""
|
||||
self.seen_events = []
|
||||
super().__init__(framework)
|
||||
|
||||
def _log_event(self, event):
|
||||
"""Log events."""
|
||||
self.seen_events.append(type(event).__name__)
|
||||
|
||||
def configure_charm(self, event):
|
||||
"""Log configure charm call."""
|
||||
super().configure_charm(event)
|
||||
self._log_event(event)
|
||||
|
||||
@property
|
||||
def public_ingress_address(self):
|
||||
"""Ingress address for charm."""
|
||||
return "openstack-images-sync.juju"
|
||||
|
||||
|
||||
class TestOISOperatorCharm(test_utils.CharmTestCase):
|
||||
"""Classes for testing openstack images sync charms."""
|
||||
|
||||
PATCHES = []
|
||||
maxDiff = None
|
||||
|
||||
def setUp(self):
|
||||
"""Setup openstack images sync tests."""
|
||||
super().setUp(charm, self.PATCHES)
|
||||
self.harness = test_utils.get_harness(
|
||||
_OISOperatorCharm,
|
||||
charm_metadata=charmcraft,
|
||||
container_calls=self.container_calls,
|
||||
charm_config=config,
|
||||
)
|
||||
|
||||
self.addCleanup(self.harness.cleanup)
|
||||
self.harness.begin()
|
||||
|
||||
def test_pebble_ready_handler(self):
|
||||
"""Test Pebble ready event is captured."""
|
||||
self.assertEqual(self.harness.charm.seen_events, [])
|
||||
test_utils.set_all_pebbles_ready(self.harness)
|
||||
self.assertEqual(self.harness.charm.seen_events, ["PebbleReadyEvent"])
|
||||
|
||||
def test_all_relations(self):
|
||||
"""Test all the charms relations."""
|
||||
self.harness.set_leader()
|
||||
test_utils.set_all_pebbles_ready(self.harness)
|
||||
test_utils.add_all_relations(self.harness)
|
||||
id_svc_rel = self.harness.model.get_relation("identity-service")
|
||||
self.harness.update_relation_data(
|
||||
id_svc_rel.id, "keystone", {"service-domain-id": "svcdomid"}
|
||||
)
|
||||
test_utils.add_complete_ingress_relation(self.harness)
|
||||
|
||||
setup_cmds = [
|
||||
["a2dissite", "000-default"],
|
||||
]
|
||||
for cmd in setup_cmds:
|
||||
self.assertIn(
|
||||
cmd,
|
||||
self.container_calls.execute[self.harness.charm.service_name],
|
||||
)
|
||||
self.check_file(
|
||||
self.harness.charm.service_name,
|
||||
"/etc/apache2/sites-enabled/http-sync.conf",
|
||||
)
|
||||
expect_entries = """cloud_name: simplestreams-glance-sync
|
||||
frequency: 3600
|
||||
mirrors:
|
||||
- content_id: '%(region)s' # Content ID choice
|
||||
custom_properties: {}
|
||||
hypervisor_mapping: false
|
||||
image_conversion: false
|
||||
item_filters:
|
||||
- release~(focal|jammy)
|
||||
- arch~(amd64)
|
||||
- ftype~(disk1.img|disk.img)
|
||||
keep_items: false
|
||||
latest_property: false
|
||||
max_items: 1
|
||||
url: http://cloud-images.ubuntu.com/releases
|
||||
path: streams/v1/index.sjson
|
||||
regions: [RegionOne]
|
||||
visibility: public
|
||||
name_prefix: auto-sync/
|
||||
output_directory: /var/www/html/simplestreams"""
|
||||
self.check_file(
|
||||
self.harness.charm.service_name,
|
||||
"/etc/openstack-images-sync/config.yaml",
|
||||
contents=expect_entries,
|
||||
)
|
11
common.sh
11
common.sh
@ -70,6 +70,10 @@ INTERNAL_OPENSTACK_HYPERVISOR_LIBS=(
|
||||
"nova_k8s"
|
||||
)
|
||||
|
||||
INTERNAL_OPENSTACK_IMAGES_SYNC_LIBS=(
|
||||
"keystone_k8s"
|
||||
)
|
||||
|
||||
INTERNAL_OVN_CENTRAL_LIBS=(
|
||||
"ovn_central_k8s"
|
||||
)
|
||||
@ -145,6 +149,10 @@ EXTERNAL_OPENSTACK_HYPERVISOR_LIBS=(
|
||||
"certificate_transfer_interface"
|
||||
)
|
||||
|
||||
EXTERNAL_OPENSTACK_IMAGES_SYNC_LIBS=(
|
||||
"traefik_k8s"
|
||||
)
|
||||
|
||||
EXTERNAL_SUNBEAM_CLUSTERD_LIBS=(
|
||||
"operator_libs_linux"
|
||||
)
|
||||
@ -321,6 +329,7 @@ declare -A INTERNAL_LIBS=(
|
||||
[octavia-k8s]=${INTERNAL_NEUTRON_LIBS[@]}
|
||||
[openstack-exporter-k8s]=${INTERNAL_KEYSTONE_LIBS[@]}
|
||||
[openstack-hypervisor]=${INTERNAL_OPENSTACK_HYPERVISOR_LIBS[@]}
|
||||
[openstack-images-sync-k8s]=${INTERNAL_OPENSTACK_IMAGES_SYNC_LIBS[@]}
|
||||
[sunbeam-clusterd]=${NULL_ARRAY[@]}
|
||||
[sunbeam-machine]=${NULL_ARRAY[@]}
|
||||
[ovn-central-k8s]=${INTERNAL_OVN_CENTRAL_LIBS[@]}
|
||||
@ -349,6 +358,7 @@ declare -A EXTERNAL_LIBS=(
|
||||
[octavia-k8s]=${EXTERNAL_OCTAVIA_LIBS[@]}
|
||||
[openstack-exporter-k8s]=${EXTERNAL_OPENSTACK_EXPORTER_LIBS[@]}
|
||||
[openstack-hypervisor]=${EXTERNAL_OPENSTACK_HYPERVISOR_LIBS[@]}
|
||||
[openstack-images-sync-k8s]=${EXTERNAL_OPENSTACK_IMAGES_SYNC_LIBS[@]}
|
||||
[sunbeam-clusterd]=${EXTERNAL_SUNBEAM_CLUSTERD_LIBS[@]}
|
||||
[sunbeam-machine]=${EXTERNAL_SUNBEAM_MACHINE_LIBS[@]}
|
||||
[ovn-central-k8s]=${EXTERNAL_OVN_CENTRAL_LIBS[@]}
|
||||
@ -377,6 +387,7 @@ declare -A CONFIG_TEMPLATES=(
|
||||
[octavia-k8s]=${CONFIG_TEMPLATES_OCTAVIA[@]}
|
||||
[openstack-exporter-k8s]=${CONFIG_TEMPLATES_HORIZON[@]}
|
||||
[openstack-hypervisor]=${NULL_ARRAY[@]}
|
||||
[openstack-images-sync-k8s]=${NULL_ARRAY[@]}
|
||||
[sunbeam-clusterd]=${NULL_ARRAY[@]}
|
||||
[sunbeam-machine]=${NULL_ARRAY[@]}
|
||||
[ovn-central-k8s]=${NULL_ARRAY[@]}
|
||||
|
@ -129,6 +129,23 @@ applications:
|
||||
debug: true
|
||||
resources:
|
||||
neutron-server-image: ghcr.io/canonical/neutron-server:2024.1
|
||||
openstack-images-sync:
|
||||
{% if openstack_images_sync_k8s is defined and openstack_images_sync_k8s is sameas true -%}
|
||||
charm: ../../../openstack-images-sync-k8s.charm
|
||||
{% else -%}
|
||||
charm: ch:openstack-images-sync-k8s
|
||||
channel: 2024.1/edge
|
||||
{% endif -%}
|
||||
base: ubuntu@22.04
|
||||
scale: 1
|
||||
trust: true
|
||||
options:
|
||||
frequency: test-do-not-use
|
||||
architecture: amd64
|
||||
release: jammy
|
||||
max-items: 1
|
||||
resources:
|
||||
openstack-images-sync-image: ghcr.io/canonical/openstack-images-sync:2024.1
|
||||
|
||||
relations:
|
||||
- - tls-operator:certificates
|
||||
@ -193,3 +210,8 @@ relations:
|
||||
- ovn-central:ovsdb-cms
|
||||
- - keystone:send-ca-cert
|
||||
- neutron:receive-ca-cert
|
||||
|
||||
- - keystone:identity-service
|
||||
- openstack-images-sync:identity-service
|
||||
- - traefik:ingress
|
||||
- openstack-images-sync:ingress-public
|
||||
|
@ -9,6 +9,7 @@ configure:
|
||||
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
|
||||
tests:
|
||||
- zaza.openstack.charm_tests.tempest.tests.TempestTestWithKeystoneMinimal
|
||||
- zaza.sunbeam.charm_tests.openstack_images_sync_k8s.tests.OpenStackImagesSyncK8sTest
|
||||
tests_options:
|
||||
trust:
|
||||
- smoke
|
||||
@ -67,3 +68,6 @@ target_deploy_status:
|
||||
neutron:
|
||||
workload-status: active
|
||||
workload-status-message-regex: '^$'
|
||||
openstack-images-sync:
|
||||
workload-status: active
|
||||
workload-status-message-regex: '^$'
|
||||
|
@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2024 Canonical Ltd.
|
||||
#
|
||||
# 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 zaza.openstack.charm_tests.test_utils as test_utils
|
||||
from zaza.openstack.utilities import openstack as openstack_utils
|
||||
|
||||
from glanceclient.v2.client import Client as GlanceClient
|
||||
import tenacity
|
||||
|
||||
class OpenStackImagesSyncK8sTest(test_utils.BaseCharmTest):
|
||||
"""Charm tests for clusterd."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Run class setup for running tests."""
|
||||
super(OpenStackImagesSyncK8sTest, cls).setUpClass(
|
||||
application_name="openstack-images-sync"
|
||||
)
|
||||
|
||||
keystone_session = openstack_utils.get_overcloud_keystone_session()
|
||||
cls.glance_client: GlanceClient = openstack_utils.get_glance_session_client(
|
||||
keystone_session
|
||||
)
|
||||
|
||||
@tenacity.retry(wait=tenacity.wait_fixed(10), stop=tenacity.stop_after_delay(180), reraise=True)
|
||||
def _wait_for_images(self):
|
||||
"""Wait for images to be downloaded."""
|
||||
images = list(self.glance_client.images.list())
|
||||
for image in images:
|
||||
if image.name.startswith("auto-sync"):
|
||||
return
|
||||
raise ValueError("No auto-sync images found")
|
||||
|
||||
def test_100_check_autosync_images_downloaded(self):
|
||||
"""Checking if glance as any auto-sync image."""
|
||||
try:
|
||||
self._wait_for_images()
|
||||
except ValueError as e:
|
||||
self.fail(str(e))
|
@ -274,6 +274,18 @@
|
||||
- rebuild
|
||||
vars:
|
||||
charm: openstack-hypervisor
|
||||
- job:
|
||||
name: charm-build-openstack-images-sync-k8s
|
||||
description: Build sunbeam openstack-images-sync-k8s charm
|
||||
run: playbooks/charm/build.yaml
|
||||
timeout: 3600
|
||||
match-on-config-updates: false
|
||||
files:
|
||||
- ops-sunbeam/ops_sunbeam/*
|
||||
- charms/openstack-images-sync-k8s/*
|
||||
- rebuild
|
||||
vars:
|
||||
charm: openstack-images-sync-k8s
|
||||
- job:
|
||||
name: charm-build-sunbeam-machine
|
||||
description: Build sunbeam-machine charm
|
||||
@ -317,6 +329,8 @@
|
||||
soft: true
|
||||
- name: charm-build-neutron-k8s
|
||||
soft: true
|
||||
- name: charm-build-openstack-images-sync-k8s
|
||||
soft: true
|
||||
- name: charm-build-ovn-central-k8s
|
||||
soft: true
|
||||
- name: charm-build-ovn-relay-k8s
|
||||
@ -328,6 +342,7 @@
|
||||
- charms/nova-k8s/*
|
||||
- charms/neutron-k8s/*
|
||||
- charms/placement-k8s/*
|
||||
- charms/openstack-images-sync-k8s/*
|
||||
- charms/ovn-central-k8s/*
|
||||
- charms/ovn-relay-k8s/*
|
||||
- rebuild
|
||||
@ -339,6 +354,7 @@
|
||||
- charm-build-nova-k8s
|
||||
- charm-build-placement-k8s
|
||||
- charm-build-neutron-k8s
|
||||
- charm-build-openstack-images-sync-k8s
|
||||
- charm-build-ovn-central-k8s
|
||||
- charm-build-ovn-relay-k8s
|
||||
# test_dir relative to project src dir
|
||||
@ -448,6 +464,7 @@
|
||||
soft: true
|
||||
- name: charm-build-ovn-central-k8s
|
||||
soft: true
|
||||
|
||||
files:
|
||||
- ops-sunbeam/ops_sunbeam/*
|
||||
- charms/heat-k8s/*
|
||||
@ -486,6 +503,7 @@
|
||||
soft: true
|
||||
- name: charm-build-horizon-k8s
|
||||
soft: true
|
||||
|
||||
files:
|
||||
- ops-sunbeam/ops_sunbeam/*
|
||||
- charms/designate-k8s/*
|
||||
@ -774,6 +792,19 @@
|
||||
- charmhub_token
|
||||
timeout: 3600
|
||||
|
||||
- job:
|
||||
name: publish-charm-openstack-images-sync-k8s
|
||||
description: |
|
||||
Publish openstack-images-sync-k8s built in gate pipeline.
|
||||
run: playbooks/charm/publish.yaml
|
||||
files:
|
||||
- ops-sunbeam/ops_sunbeam/*
|
||||
- charms/openstack-images-sync-k8s/*
|
||||
- rebuild
|
||||
secrets:
|
||||
- charmhub_token
|
||||
timeout: 3600
|
||||
|
||||
- job:
|
||||
name: publish-charm-ovn-central-k8s
|
||||
description: |
|
||||
|
@ -80,6 +80,8 @@
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-openstack-hypervisor:
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-openstack-images-sync-k8s:
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-sunbeam-machine:
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-sunbeam-clusterd:
|
||||
@ -133,6 +135,8 @@
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-openstack-hypervisor:
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-openstack-images-sync-k8s:
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-sunbeam-machine:
|
||||
nodeset: ubuntu-jammy
|
||||
- charm-build-sunbeam-clusterd:
|
||||
@ -190,6 +194,8 @@
|
||||
nodeset: ubuntu-jammy
|
||||
- publish-charm-openstack-hypervisor:
|
||||
nodeset: ubuntu-jammy
|
||||
- publish-charm-openstack-images-sync-k8s:
|
||||
nodeset: ubuntu-jammy
|
||||
- publish-charm-sunbeam-machine:
|
||||
nodeset: ubuntu-jammy
|
||||
- publish-charm-sunbeam-clusterd:
|
||||
|
@ -1,75 +1,75 @@
|
||||
- secret:
|
||||
name: charmhub_token
|
||||
data:
|
||||
# Generated on 2024-02-02T09:33:56+00:00 with 90 days ttl
|
||||
# Generated on 2024-04-11T11:37:37+00:00 with 90 days ttl
|
||||
value: !encrypted/pkcs1-oaep
|
||||
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- eh8Cv8PHxVNy7RfyZ15RSpyeQLPPRU58+IKr+VxgbpLtdwgfMu2w58Uj3AeQlfHCg4+/0
|
||||
PUv+926/8WemH380dh4hx0pnSHyHvof2h2dMoThCt/vLcF09YhNZMY1bW5NY3uWu98Gqs
|
||||
fNvGb8qGOGRZjm2mys+FqcDeyLoSb+YrFTHjYKZLwbvyJeiWUR9SHYuyu0/0WeJMZoKFK
|
||||
beLvk3kawCObDGxEm8EBMEwIRUl8SfORwzGO3SATBB+jen4Dd63uwkOutcqt10cvvRbTJ
|
||||
QzLTLGh2vYRhGTXggMKpEfTZY8xc0CVdRyaK7uEfnbqMEUdsDFBDlfQ8EWDgOo9EW2Ggp
|
||||
EJ0SYFOBbQOU0CuU9Y/QVt2aXAe3T4AzKINqEmayaZvNqmQH4WgVVG9stddKg8B89nnMG
|
||||
BYgfg+H+emBdaSNtkDUKi0VPotxA2iVurrqDekOEBvjavmI3mlKHwUyZZYffEIP7lNt7N
|
||||
lvpTZQd+J6nKy6vF3i2DU+Ti9l7zah8EnfCS8so5qCcGm1IkZn+6Ji+twIR8RPoJdqDkH
|
||||
cqAtAsyGb5/reCMOVsUVu9dYB5yt7G7OYerIA/cDCstyYWf5oXcIwQpvFb9NxO0v2/vNx
|
||||
zh9kUQkvW03QM++37T3O/2wEFOBDVV3oTyACMhZjWhX5oTC8v4I1orYJE8ej4U=
|
||||
- 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
- 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
- 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
- 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
|
||||
|
@ -48,6 +48,7 @@
|
||||
keystone-ldap-k8s: 2024.1/edge
|
||||
openstack-exporter-k8s: 2024.1/edge
|
||||
openstack-hypervisor: 2024.1/edge
|
||||
openstack-images-sync-k8s: 2024.1/edge
|
||||
sunbeam-machine: 2024.1/edge
|
||||
sunbeam-clusterd: 2024.1/edge
|
||||
tempest-k8s: 2024.1/edge
|
||||
|
Loading…
Reference in New Issue
Block a user