Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ba5d0a5
Better conditions for creating Floating IPs
EmilienM Nov 19, 2024
fcbe290
Merge pull request #2270 from kubernetes-sigs/backport-0.10-fip
k8s-ci-robot Nov 25, 2024
c62b21f
Fix deletion of cluster when bastion image missing
lentzi90 Nov 28, 2024
3727279
Re-work release process
EmilienM Nov 26, 2024
3170ea9
Merge pull request #2293 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Nov 28, 2024
efcbbe9
Merge pull request #2291 from Nordix/lentzi90/fix-bastion-deletion-re…
k8s-ci-robot Dec 3, 2024
1fa0c34
Add libvirt resource type for create_devstack.sh
lentzi90 Nov 14, 2024
523cf06
Run devstack on ubuntu 24.04 and bump to 2024.2
lentzi90 Dec 4, 2024
d3fd177
test: Temporarily disable deep image inspection in Nova
stephenfin Dec 5, 2024
8297241
Merge pull request #2304 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Dec 6, 2024
aee4a46
ci/devstack: host tuning
EmilienM Dec 9, 2024
56b2322
Merge pull request #2309 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Dec 9, 2024
e2807f5
devstack: build OVN from source
EmilienM Dec 11, 2024
1baa9e1
Merge pull request #2325 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Dec 12, 2024
39eea80
CI: Increase IOPS for devstack disk
lentzi90 Dec 11, 2024
ed073e6
Merge pull request #2326 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Dec 12, 2024
5816690
Devstack: Make boot volume optional on openstack
lentzi90 Dec 11, 2024
354dc06
Merge pull request #2327 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Dec 13, 2024
fb4c8a3
Update cloudbuild image
lentzi90 Jan 14, 2025
d4bfe7b
Merge pull request #2369 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Jan 14, 2025
1f1136f
fix: create lbaas in specified subnet
simonostendorf Dec 18, 2024
787b4a8
Merge pull request #2371 from Nordix/lentzi90/release-0.10-lb-subnet-fix
k8s-ci-robot Jan 15, 2025
c09d580
Update OWNERS_ALIASES
EmilienM Jan 14, 2025
d0a76bf
Merge pull request #2373 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot Jan 15, 2025
68e7b13
Ensure that existing ports also have correct tags and trunks
lentzi90 Jan 24, 2025
fcf6f1f
Merge pull request #2356 from Nordix/lentzi90/ensure-ports-tags-relea…
k8s-ci-robot Jan 27, 2025
23d4eb6
allow switching from filter.name to id in openstackclusterspec networ…
okozachenko1203 Apr 16, 2025
e1fb93f
Merge pull request #2544 from k8s-infra-cherrypick-robot/cherry-pick-…
k8s-ci-robot May 12, 2025
02682af
Merge https://github.com/kubernetes-sigs/cluster-api-provider-opensta…
May 15, 2025
04a75f4
CARRY: Re-add slices package
mandre Jun 23, 2025
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
44 changes: 44 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: release

on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

permissions:
contents: write # Allow to create a release.

jobs:
build:
name: create draft release
runs-on: ubuntu-latest
steps:
- name: Set env
run: echo "RELEASE_TAG=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
with:
fetch-depth: 0
- name: Calculate go version
run: echo "go_version=$(make go-version)" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # tag=v5.1.0
with:
go-version: ${{ env.go_version }}
- name: generate release artifacts
run: |
make release
- name: generate release notes
# Ignore failures for release-notes generation so they could still get
# generated manually before publishing.
run: |
make generate-release-notes || echo "Failed to generate release notes" >> _releasenotes/${{ env.RELEASE_TAG }}.md
env:
GH_TOKEN: ${{ github.token }}
- name: Release
uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # tag=v2.1.0
with:
draft: true
files: out/*
body_path: _releasenotes/${{ env.RELEASE_TAG }}.md
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ cscope.*
*.test
/hack/.test-cmd-auth

# Generated release notes
_releasenotes

# JUnit test output from ginkgo e2e tests
/junit*.xml

Expand Down
42 changes: 38 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export GOTOOLCHAIN=go1.22.8
export GO111MODULE=on
unexport GOPATH

# Go
GO_VERSION ?= 1.22.7

# Directories.
ARTIFACTS ?= $(REPO_ROOT)/_artifacts
TOOLS_DIR := hack/tools
Expand Down Expand Up @@ -359,8 +362,25 @@ staging-manifests:
##@ Release
## --------------------------------------

ifneq (,$(findstring -,$(RELEASE_TAG)))
PRE_RELEASE=true
endif
PREVIOUS_TAG ?= $(shell git tag -l | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$$" | sort -V | grep -B1 $(RELEASE_TAG) | head -n 1 2>/dev/null)
## set by Prow, ref name of the base branch, e.g., main
RELEASE_DIR := out
RELEASE_NOTES_DIR := _releasenotes

.PHONY: $(RELEASE_DIR)
$(RELEASE_DIR):
mkdir -p $@
mkdir -p $(RELEASE_DIR)/

.PHONY: $(RELEASE_NOTES_DIR)
$(RELEASE_NOTES_DIR):
mkdir -p $(RELEASE_NOTES_DIR)/

.PHONY: $(BUILD_DIR)
$(BUILD_DIR):
@mkdir -p $(BUILD_DIR)

.PHONY: list-staging-releases
list-staging-releases: ## List staging images for image promotion
Expand Down Expand Up @@ -435,9 +455,14 @@ upload-gh-artifacts: $(GH) ## Upload artifacts to Github release
release-alias-tag: # Adds the tag to the last build tag.
gcloud container images add-tag -q $(CONTROLLER_IMG):$(TAG) $(CONTROLLER_IMG):$(RELEASE_ALIAS_TAG)

.PHONY: release-notes
release-notes: $(RELEASE_NOTES) ## Generate release notes
$(RELEASE_NOTES) $(RELEASE_NOTES_ARGS)
.PHONY: generate-release-notes ## Generate release notes
generate-release-notes: $(RELEASE_NOTES_DIR) $(RELEASE_NOTES)
# Reset the file
echo -n > $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md
if [ -n "${PRE_RELEASE}" ]; then \
echo -e ":rotating_light: This is a RELEASE CANDIDATE. Use it only for testing purposes. If you find any bugs, file an [issue](https://github.com/kubernetes-sigs/cluster-api-provider-openstack/issues/new/choose).\n" >> $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md; \
fi
"$(RELEASE_NOTES)" --from=$(PREVIOUS_TAG) >> $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md

.PHONY: templates
templates: ## Generate cluster templates
Expand Down Expand Up @@ -557,3 +582,12 @@ compile-e2e: ## Test e2e compilation

.PHONY: FORCE
FORCE:

## --------------------------------------
## Helpers
## --------------------------------------

##@ helpers:

go-version: ## Print the go version we use to compile our binaries and images
@echo $(GO_VERSION)
3 changes: 2 additions & 1 deletion OWNERS_ALIASES
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ aliases:
- vincepri
cluster-api-openstack-maintainers:
- emilienm
- jichenjc
- lentzi90
- mdbooth
cluster-api-openstack-reviewers:
cluster-api-openstack-emeritus-maintainers:
- jichenjc
5 changes: 1 addition & 4 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@ The content of the release notes differs depending on the type of release, speci
for review and the promotion of the image.
1. Run `make release` to build artifacts to be attached to the GitHub release.
1. Generate and finalize the release notes and save them for the next step.
- Run `make release-notes RELEASE_NOTES_ARGS="--from <tag>"`.
- Depending on the type of release, substitute `<tag>` with the following:
- Stable releases: tag of the last stable release
- Pre-releases*: tag of the latest pre-release (or last stable release if there isn't one)
- Run `make release-notes`.
- Pay close attention to the `## :question: Sort these by hand` section, as it contains items that need to be manually sorted.
1. Create a draft release in GitHub based on the tag created above
- Name the release `Release [VERSION]` where VERSION is the full version string.
Expand Down
2 changes: 1 addition & 1 deletion cloudbuild-nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ options:
substitution_option: ALLOW_LOOSE
machineType: 'N1_HIGHCPU_8'
steps:
- name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20220609-2e4c91eb7e'
- name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20241229-5dc092c636'
entrypoint: make
env:
- DOCKER_CLI_EXPERIMENTAL=enabled
Expand Down
2 changes: 1 addition & 1 deletion cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ options:
substitution_option: ALLOW_LOOSE
machineType: 'N1_HIGHCPU_8'
steps:
- name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20220609-2e4c91eb7e'
- name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20241229-5dc092c636'
entrypoint: make
env:
- DOCKER_CLI_EXPERIMENTAL=enabled
Expand Down
25 changes: 15 additions & 10 deletions controllers/openstackcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,11 @@ func (r *OpenStackClusterReconciler) reconcileDelete(ctx context.Context, scope
// A bastion may have been created if cluster initialisation previously reached populating the network status
// We attempt to delete it even if no status was written, just in case
if openStackCluster.Status.Network != nil {
// Attempt to resolve bastion resources before delete. We don't need to worry about starting if the resources have changed on update.
// Attempt to resolve bastion resources before delete.
// Even if we fail, we need to continue with the deletion or risk getting stuck.
// For example, if the image doesn't exist, we do not have a bastion.
if _, err := resolveBastionResources(scope, clusterResourceName, openStackCluster); err != nil {
return reconcile.Result{}, err
scope.Logger().Info("Failed to resolve bastion, continuing.", "error", err)
}

if err := deleteBastion(scope, cluster, openStackCluster); err != nil {
Expand Down Expand Up @@ -614,11 +616,7 @@ func getOrCreateBastionPorts(openStackCluster *infrav1.OpenStackCluster, network
return errors.New("bastion resources are nil")
}

if len(desiredPorts) == len(resources.Ports) {
return nil
}

err := networkingService.CreatePorts(openStackCluster, desiredPorts, resources)
err := networkingService.EnsurePorts(openStackCluster, desiredPorts, resources)
if err != nil {
return fmt.Errorf("failed to create ports for bastion %s: %w", bastionName(openStackCluster.Name), err)
}
Expand Down Expand Up @@ -664,14 +662,19 @@ func resolveLoadBalancerNetwork(openStackCluster *infrav1.OpenStackCluster, netw

// Filter out only relevant subnets specified by the spec
lbNetStatus.Subnets = []infrav1.Subnet{}
for _, s := range lbSpec.Subnets {
for i := range lbSpec.Subnets {
s := lbSpec.Subnets[i]
matchFound := false
for _, subnetID := range lbNet.Subnets {
if s.ID != nil && subnetID == *s.ID {
subnet, err := networkingService.GetSubnetByParam(&s)
if s.ID != nil && subnetID == *s.ID && err == nil {
matchFound = true
lbNetStatus.Subnets = append(
lbNetStatus.Subnets, infrav1.Subnet{
ID: *s.ID,
ID: subnet.ID,
Name: subnet.Name,
CIDR: subnet.CIDR,
Tags: subnet.Tags,
})
}
}
Expand All @@ -680,6 +683,8 @@ func resolveLoadBalancerNetwork(openStackCluster *infrav1.OpenStackCluster, netw
return fmt.Errorf("no subnet match was found in the specified network (specified subnet: %v, available subnets: %v)", s, lbNet.Subnets)
}
}

openStackCluster.Status.APIServerLoadBalancer.LoadBalancerNetwork = lbNetStatus
}
}

Expand Down
6 changes: 6 additions & 0 deletions controllers/openstackcluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ var _ = Describe("OpenStackCluster controller", func() {
server.Status = "ACTIVE"

networkClientRecorder := mockScopeFactory.NetworkClient.EXPECT()
// One list for adopting and one for ensuring the ports and tags are correct
networkClientRecorder.ListPort(gomock.Any()).Return([]ports.Port{{ID: "portID1"}}, nil)
networkClientRecorder.ListPort(gomock.Any()).Return([]ports.Port{{ID: "portID1"}}, nil)

computeClientRecorder := mockScopeFactory.ComputeClient.EXPECT()
Expand Down Expand Up @@ -362,6 +364,7 @@ var _ = Describe("OpenStackCluster controller", func() {

networkClientRecorder := mockScopeFactory.NetworkClient.EXPECT()
networkClientRecorder.ListPort(gomock.Any()).Return([]ports.Port{{ID: "portID1"}}, nil)
networkClientRecorder.ListPort(gomock.Any()).Return([]ports.Port{{ID: "portID1"}}, nil)

computeClientRecorder := mockScopeFactory.ComputeClient.EXPECT()
computeClientRecorder.GetServer("adopted-fip-bastion-uuid").Return(&server, nil)
Expand Down Expand Up @@ -445,6 +448,9 @@ var _ = Describe("OpenStackCluster controller", func() {
computeClientRecorder := mockScopeFactory.ComputeClient.EXPECT()
computeClientRecorder.GetServer("requeue-bastion-uuid").Return(&server, nil)

networkClientRecorder := mockScopeFactory.NetworkClient.EXPECT()
networkClientRecorder.ListPort(gomock.Any()).Return([]ports.Port{{ID: "portID1"}}, nil)

res, err := reconcileBastion(scope, capiCluster, testCluster)
Expect(testCluster.Status.Bastion).To(Equal(&infrav1.BastionStatus{
ID: "requeue-bastion-uuid",
Expand Down
6 changes: 1 addition & 5 deletions controllers/openstackmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,11 +752,7 @@ func getOrCreateMachinePorts(openStackMachine *infrav1.OpenStackMachine, network
}
desiredPorts := resolved.Ports

if len(desiredPorts) == len(resources.Ports) {
return nil
}

if err := networkingService.CreatePorts(openStackMachine, desiredPorts, resources); err != nil {
if err := networkingService.EnsurePorts(openStackMachine, desiredPorts, resources); err != nil {
return fmt.Errorf("creating ports: %w", err)
}

Expand Down
19 changes: 19 additions & 0 deletions hack/ci/cloud-init/controller.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
VERBOSE=True
LOG_COLOR=True

# Host tuning
ENABLE_SYSCTL_MEM_TUNING="True"
ENABLE_SYSCTL_NET_TUNING="True"
ENABLE_ZSWAP="True"

# Octavia
enable_plugin octavia https://github.com/openstack/octavia stable/${OPENSTACK_RELEASE}
enable_plugin octavia-dashboard https://github.com/openstack/octavia-dashboard stable/${OPENSTACK_RELEASE}
Expand Down Expand Up @@ -43,6 +48,14 @@
OVN_L3_CREATE_PUBLIC_NETWORK="True"
Q_AGENT="ovn"

# WORKAROUND:
# https://github.com/kubernetes-sigs/cluster-api-provider-openstack/issues/2320
# OVN built from source using LTS versions. Should be removed once OVS is more stable without the pin.
# https://opendev.org/openstack/neutron/src/commit/83de306105f9329e24c97c4af6c3886de20e7d70/zuul.d/tempest-multinode.yaml#L603-L604
OVN_BUILD_FROM_SOURCE=True
OVN_BRANCH=branch-24.03
OVS_BRANCH=branch-3.3

# Octavia
ENABLED_SERVICES+=,octavia,o-api,o-cw,o-hm,o-hk,o-da

Expand Down Expand Up @@ -89,6 +102,12 @@
# query_placement_for_availability_zone is the default from Xena
query_placement_for_availability_zone = True

[workarounds]
# FIXME(stephenfin): This is temporary while we get to the bottom of
# https://bugs.launchpad.net/nova/+bug/2091114 It should not be kept after
# we bump to 2025.1
disable_deep_image_inspection = True

[[post-config|$CINDER_CONF]]
[DEFAULT]
storage_availability_zone = ${PRIMARY_AZ}
Expand Down
19 changes: 19 additions & 0 deletions hack/ci/cloud-init/worker.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
VERBOSE=True
LOG_COLOR=True

# Host tuning
ENABLE_SYSCTL_MEM_TUNING="True"
ENABLE_SYSCTL_NET_TUNING="True"
ENABLE_ZSWAP="True"

DATABASE_PASSWORD=secretdatabase
RABBIT_PASSWORD=secretrabbit
ADMIN_PASSWORD=secretadmin
Expand Down Expand Up @@ -39,6 +44,14 @@
Q_ML2_PLUGIN_MECHANISM_DRIVERS="ovn,logger"
Q_AGENT="ovn"

# WORKAROUND:
# https://github.com/kubernetes-sigs/cluster-api-provider-openstack/issues/2320
# OVN built from source using LTS versions. Should be removed once OVS is more stable without the pin.
# https://opendev.org/openstack/neutron/src/commit/83de306105f9329e24c97c4af6c3886de20e7d70/zuul.d/tempest-multinode.yaml#L603-L604
OVN_BUILD_FROM_SOURCE=True
OVN_BRANCH=branch-24.03
OVS_BRANCH=branch-3.3

# Additional services
ENABLED_SERVICES+=${OPENSTACK_ADDITIONAL_SERVICES}
DISABLED_SERVICES+=${OPENSTACK_DISABLED_SERVICES}
Expand All @@ -47,6 +60,12 @@
[DEFAULT]
cpu_allocation_ratio = 2.0

[workarounds]
# FIXME(stephenfin): This is temporary while we get to the bottom of
# https://bugs.launchpad.net/nova/+bug/2091114 It should not be kept after
# we bump to 2025.1
disable_deep_image_inspection = True

[[post-config|$CINDER_CONF]]
[DEFAULT]
storage_availability_zone = ${SECONDARY_AZ}
Expand Down
11 changes: 9 additions & 2 deletions hack/ci/create_devstack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ source "${scriptdir}/${RESOURCE_TYPE}.sh"

CLUSTER_NAME=${CLUSTER_NAME:-"capo-e2e"}

OPENSTACK_RELEASE=${OPENSTACK_RELEASE:-"2023.2"}
OPENSTACK_RELEASE=${OPENSTACK_RELEASE:-"2024.2"}
OPENSTACK_ENABLE_HORIZON=${OPENSTACK_ENABLE_HORIZON:-"false"}

# Devstack will create a provider network using this range
Expand All @@ -47,6 +47,9 @@ PRIVATE_NETWORK_CIDR=${PRIVATE_NETWORK_CIDR:-"10.0.3.0/24"}
CONTROLLER_IP=${CONTROLLER_IP:-"10.0.3.15"}
WORKER_IP=${WORKER_IP:-"10.0.3.16"}

SKIP_INIT_INFRA=${SKIP_INIT_INFRA:-}
SKIP_SECONDARY_AZ=${SKIP_SECONDARY_AZ:-}

PRIMARY_AZ=testaz1
SECONDARY_AZ=testaz2

Expand Down Expand Up @@ -273,7 +276,11 @@ function main() {
# is available, and wait if it is not.
#
# For efficiency, tests which require multi-AZ SHOULD run as late as possible.
create_worker
if [[ -n "${SKIP_SECONDARY_AZ:-}" ]]; then
echo "Skipping worker creation..."
else
create_worker
fi

public_ip=$(get_public_ip)
cat << EOF > "${REPO_ROOT_ABSOLUTE}/clouds.yaml"
Expand Down
4 changes: 2 additions & 2 deletions hack/ci/gce-project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ function create_vm {
--zone "$GCP_ZONE" \
--enable-nested-virtualization \
--image-project ubuntu-os-cloud \
--image-family ubuntu-2204-lts \
--boot-disk-size 200G \
--image-family ubuntu-2404-lts-amd64 \
--boot-disk-size 500G \
--boot-disk-type pd-ssd \
--can-ip-forward \
--tags http-server,https-server,novnc,openstack-apis \
Expand Down
Loading