Skip to content
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
78 changes: 39 additions & 39 deletions .github/assets/testing/edge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,39 @@ core:
logging-config: "<root>=WARNING;unit=DEBUG"
charms:
cinder-volume:
channel: 2024.1/edge
channel: 2026.1/edge
cinder-volume-ceph:
channel: 2024.1/edge
channel: 2026.1/edge
cinder-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
glance-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
horizon-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
keystone-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
neutron-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
nova-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
openstack-hypervisor:
channel: 2024.1/edge
channel: 2026.1/edge
config:
snap-channel: 2024.1/edge
snap-channel: 2026.1/edge
ovn-central-k8s:
channel: 24.03/edge
channel: 26.03/edge
ovn-relay-k8s:
channel: 24.03/edge
channel: 26.03/edge
placement-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
sunbeam-clusterd:
channel: 2024.1/edge
channel: 2026.1/edge
config:
snap-channel: 2024.1/edge
snap-channel: 2026.1/edge
sunbeam-machine:
channel: 2024.1/edge
channel: 2026.1/edge
epa-orchestrator:
channel: 2024.1/edge
channel: 2026.1/edge
microceph:
channel: squid/edge
config:
Expand All @@ -61,32 +61,32 @@ features:
software:
charms:
ironic-conductor-k8s:
channel: 2025.1/edge
channel: 2026.1/edge
ironic-k8s:
channel: 2025.1/edge
channel: 2026.1/edge
nova-ironic-k8s:
channel: 2025.1/edge
channel: 2026.1/edge
neutron-baremetal-switch-config-k8s:
channel: 2025.1/edge
channel: 2026.1/edge
neutron-generic-switch-config-k8s:
channel: 2025.1/edge
channel: 2026.1/edge
caas:
software:
charms:
magnum-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
dns:
software:
charms:
designate-bind-k8s:
channel: 9/edge
designate-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
images-sync:
software:
charms:
openstack-images-sync-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
instance-recovery:
software:
charms:
Expand All @@ -95,54 +95,54 @@ features:
consul-client:
channel: 1.19/edge
masakari-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
ldap:
software:
charms:
keystone-ldap-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
loadbalancer:
software:
charms:
octavia-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
orchestration:
software:
charms:
heat-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
resource-optimization:
software:
charms:
watcher-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
secrets:
software:
charms:
barbican-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
shared-filesystem:
software:
charms:
manila-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
manila-cephfs-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
manila-data:
channel: 2024.1/edge
channel: 2026.1/edge
telemetry:
software:
charms:
aodh-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
ceilometer-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
gnocchi-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
openstack-exporter-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
validation:
software:
charms:
tempest-k8s:
channel: 2024.1/edge
channel: 2026.1/edge
1 change: 1 addition & 0 deletions .github/workflows/build-snap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jobs:
sudo snap remove --purge lxd
sudo snap install --channel 3.6 juju

sudo snap install core26 --channel=latest/edge || true
sudo snap install ${{ needs.build.outputs.snap }} --dangerous
sudo snap connect openstack:juju-bin juju:juju-bin
openstack.sunbeam prepare-node-script --bootstrap | bash -x
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/test-snap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ on:
snap-channel:
description: Specify openstack snap channel
required: true
default: 2024.1/candidate
default: 2026.1/candidate
type: string
os-charm-channel:
description: Specify openstack charms channel
required: true
default: 2024.1/candidate
default: 2026.1/candidate
type: string
ovn-charm-channel:
description: Specify ovn charms channel
required: true
default: 24.03/candidate
default: 26.03/candidate
type: string
microceph-charm-channel:
description: Specify microceph charms channel
Expand Down Expand Up @@ -63,8 +63,8 @@ jobs:
run: |
export COLUMNS=256
set +x
# 2023.x, 2024.1/beta does not support k8s provider
if [[ ! ${{ inputs.snap-channel }} =~ "2024.1/edge" && ${{ inputs.k8s-provider }} == "k8s" ]]; then echo "k8s provider not supported"; exit 1; fi
# 2023.x, 2026.1/beta does not support k8s provider
if [[ ! ${{ inputs.snap-channel }} =~ "2026.1/edge" && ${{ inputs.k8s-provider }} == "k8s" ]]; then echo "k8s provider not supported"; exit 1; fi

sudo snap remove --purge lxd
sudo snap install juju --channel 3.6/stable
Expand All @@ -73,9 +73,9 @@ jobs:
sudo snap connect openstack:juju-bin juju:juju-bin
sudo snap set openstack k8s.provider=${{ inputs.k8s-provider }}

# New manifest is applicable from 2024.1/edge
# Change this condition once 2024.1/edge is released to beta
if [[ ${{ inputs.snap-channel }} =~ "2024.1/edge" ]];
# New manifest is applicable from 2026.1/edge
# Change this condition once 2026.1/edge is released to beta
if [[ ${{ inputs.snap-channel }} =~ "2026.1/edge" ]];
then
cp .github/assets/testing/manifest.yml manifest.yml
else
Expand Down
72 changes: 72 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# CLAUDE.md — OpenStack Snap Migration Guide (Gazpacho 2026.1 / Ubuntu 26.04 / Python 3.14)

## Project Context
You are an expert software engineer.
This is a snap package for OpenStack components, being migrated to:
- **OpenStack release:** 2026.1 (Gazpacho)
- **Ubuntu base:** 26.04 (core26 snap base)
- **Python:** 3.14

## Key Files

- `pyproject.toml` — package metadata, dependencies, entry points
- `snap/snapcraft.yaml` — snap build definition (base, parts, apps, layouts)
- `tox.ini` — test runner config (uses `uv` for unit tests)
- `openstack_hypervisor/` — main Python package
- `templates/` — Jinja2 config templates for OpenStack services
- `tests/unit/` — unit tests (pytest)

## Migration Checklist

### pyproject.toml
- Set `version = "2026.1"`
- Set `requires-python = "~=3.14.0"`
- Update classifiers to include `Programming Language :: Python :: 3.14`
- Review all dependencies for Python 3.14 compatibility

### snap/snapcraft.yaml
- Set `base: core26` and `build-base: devel` (until core26 is stable)
- Update all `PYTHONPATH` references from `python3.XX` → `python3.14`
- Update any hardcoded Python paths in parts, apps, and environment blocks
- Bump OpenStack component versions to Gazpacho (2026.1) in source-branch/source-tag fields
- Review channel for stage-snaps (e.g. `latest/edge` during development)

### Python 3.14 Compatibility Issues

#### `os.memfd_create` not available in frozen `os` module
- **Symptom:** `AttributeError: <module 'os' (frozen)> does not have the attribute 'memfd_create'`
- **Cause:** In CPython 3.14, the `os` module is frozen and `os.memfd_create` may not be present in all builds (especially CI runners). `unittest.mock.patch` raises `AttributeError` when it tries to look up an attribute that doesn't exist.
- **Fix:** Add `create=True` to `@patch()` decorators for platform-specific `os` functions:
```python
# Before (breaks on 3.14):
@patch("mymodule.os.memfd_create", return_value=10)

# After (works everywhere):
@patch("mymodule.os.memfd_create", create=True, return_value=10)
```
- **General rule:** Any `@patch` targeting a platform-specific or optional attribute in a frozen stdlib module needs `create=True`.

#### Other common Python 3.14 changes to watch for
- Deprecated functions removed from `collections`, `typing`, `importlib`, etc.
- `ctypes.Structure` with `_pack_` now warns about `_layout_` (see `pyroute2` warnings) — these are upstream dependency issues, not things to fix in the snap code.
- XML ElementTree `.find()` truth-value testing is deprecated — use `elem is not None` or `len(elem)` instead.

### Testing
- Tests use `uv` via tox: `tox -e unit`
- The `uv` lock file should be regenerated after dependency changes: `tox -e lock`
- Use `--frozen --isolated --extra=dev` flags (already configured in `tox.ini`)

## Common Patterns in This Codebase

- Services are defined in `services.py` with a `run(snap)` method pattern
- Configuration is rendered from Jinja2 templates in `templates/`
- Snap hooks (configure, install) are in `hooks.py`
- CLI uses Click, defined under `cli/`
- Tests use pytest with `unittest.mock` patching; fixtures in `conftest.py`

## Tips

- When patching stdlib functions that are platform-specific (e.g., Linux-only syscalls like `memfd_create`, `copy_file_range`, `sendfile`), always use `create=True` in `@patch`.
- If CI fails with `AttributeError: <module 'X' (frozen)> does not have the attribute 'Y'`, the frozen module in 3.14 is likely missing that attribute — use `create=True`.
- The snap uses `setpriv` to drop privileges for services — don't remove `--reuid`/`--regid` from subprocess calls.
- `snapcraft.yaml` is large (~900 lines); search for the specific part name when editing.
4 changes: 2 additions & 2 deletions cloud/etc/deploy-cinder-volume/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ resource "juju_application" "cinder-volume" {
name = "cinder-volume"
channel = var.charm_cinder_volume_channel
revision = var.charm_cinder_volume_revision
base = "ubuntu@24.04"
base = "ubuntu@26.04"
}

config = merge({
Expand Down Expand Up @@ -110,7 +110,7 @@ resource "juju_application" "cinder-volume-ceph" {
name = "cinder-volume-ceph"
channel = var.charm_cinder_volume_ceph_channel
revision = var.charm_cinder_volume_ceph_revision
base = "ubuntu@24.04"
base = "ubuntu@26.04"
}

config = var.charm_cinder_volume_ceph_config
Expand Down
6 changes: 3 additions & 3 deletions cloud/etc/deploy-cinder-volume/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
variable "charm_cinder_volume_channel" {
description = "Operator channel for cinder_volume deployment"
type = string
default = "2024.1/stable"
default = "2026.1/stable"
}

variable "charm_cinder_volume_revision" {
Expand All @@ -21,13 +21,13 @@ variable "charm_cinder_volume_config" {

variable "cinder_volume_channel" {
description = "Cinder Volume channel to deploy, not the operator channel"
default = "2024.1/stable"
default = "2026.1/stable"
}

variable "charm_cinder_volume_ceph_channel" {
description = "Operator channel for cinder_volume_ceph deployment"
type = string
default = "2024.1/stable"
default = "2026.1/stable"
}

variable "charm_cinder_volume_ceph_revision" {
Expand Down
2 changes: 1 addition & 1 deletion cloud/etc/deploy-k8s/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ resource "juju_application" "k8s" {
name = "k8s"
channel = var.k8s_channel
revision = var.k8s_revision
base = "ubuntu@24.04"
base = "ubuntu@26.04"
}

config = var.k8s_config
Expand Down
2 changes: 1 addition & 1 deletion cloud/etc/deploy-microceph/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ resource "juju_application" "microceph" {
name = "microceph"
channel = var.charm_microceph_channel
revision = var.charm_microceph_revision
base = "ubuntu@24.04"
base = "ubuntu@26.04"
}

config = merge({
Expand Down
8 changes: 4 additions & 4 deletions cloud/etc/deploy-microovn/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ resource "juju_application" "openstack-network-agents" {
charm {
name = "openstack-network-agents"
channel = var.charm_openstack_network_agents_channel
base = "ubuntu@24.04"
base = "ubuntu@26.04"
revision = var.charm_openstack_network_agents_revision
}

Expand All @@ -45,7 +45,7 @@ resource "juju_application" "microcluster-token-distributor" {
charm {
name = "microcluster-token-distributor"
channel = var.charm_microcluster_token_distributor_channel
base = "ubuntu@24.04"
base = "ubuntu@26.04"
revision = var.charm_microcluster_token_distributor_revision
}

Expand All @@ -61,7 +61,7 @@ resource "juju_application" "microovn" {
charm {
name = "microovn"
channel = var.charm_microovn_channel
base = "ubuntu@24.04"
base = "ubuntu@26.04"
revision = var.charm_microovn_revision
}

Expand All @@ -82,7 +82,7 @@ resource "juju_application" "sunbeam-ovn-proxy" {
charm {
name = "sunbeam-ovn-proxy"
channel = var.charm_sunbeam_ovn_proxy_channel
base = "ubuntu@24.04"
base = "ubuntu@26.04"
revision = var.charm_sunbeam_ovn_proxy_revision
}

Expand Down
Loading
Loading