Skip to content

Commit

Permalink
move keepalived here from BMO repo
Browse files Browse the repository at this point in the history
This commit:
 - Moves the project used to build the Metal3 keepalived container from
   the BMO repository to this repository
 - Adds support for customizable config file location for the keepalived
   container
 - Adds container building github workflow for keepalived
 - Adds keepalived release workflow
 - Adds release document for the whole of the utility-images repository

These changes were needed for two related reasons.
 - The community has decided that there is no reason to keep the keepalived
   files in BMO and they much better fit for the utility-images repository.
 - There is ongoing work to turn the ironic pod compatible with the K8s pod
   security option that enforces the use of read only mode for the container
   file system and the current containers deployed as part of the Ironic pod
   such as keepalived are not compatible without modification.

Note: release workflows and documentation is a new concept for this
repository and a bit differ from other Metal3 repos because different
projects within the repo get released independently.

Signed-off-by: Adam Rozman <[email protected]>
  • Loading branch information
Rozzii committed Jan 31, 2025
1 parent 7bdb949 commit 307ec43
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/build-images-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,15 @@ jobs:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
build_keepalived:
name: Build keepalived container image
if: github.repository == 'metal3-io/utility-images'
uses: metal3-io/project-infra/.github/workflows/container-image-build.yml@main
with:
image-name: 'keepalived'
dockerfile-directory: keepalived
pushImage: true
secrets:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
138 changes: 138 additions & 0 deletions .github/workflows/keepalived-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# This code is borrowed from https://github.com/kubernetes-sigs/cluster-api/blob/main/.github/workflows/release.yaml
name: Create Release

on:
push:
branches:
- main
paths:
- 'keepalived/releasenotes/*.md'

permissions: {}

jobs:
push_release_tags:
permissions:
contents: write
runs-on: ubuntu-latest
outputs:
release_tag: ${{ steps.release-version.outputs.release_version }}
if: github.repository == 'metal3-io/utility-images'
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@bab30c2299617f6615ec02a68b9a40d10bd21366 # tag=v45.0.5
- name: Get release version
id: release-version
run: |
if [[ ${{ steps.changed-files.outputs.all_changed_files_count }} != 1 ]]; then
echo "1 release notes file should be changed to create a release tag, found ${{ steps.changed-files.outputs.all_changed_files_count }}"
exit 1
fi
for changed_file in ${{ steps.changed-files.outputs.all_changed_files }}; do
export RELEASE_VERSION=$(echo "${changed_file}" | grep -oP '(?<=/)[^/]+(?=\.md)')
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> ${GITHUB_ENV}
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> ${GITHUB_OUTPUT}
if [[ "${RELEASE_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$ ]]; then
echo "Valid semver: ${RELEASE_VERSION}"
else
echo "Invalid semver: ${RELEASE_VERSION}"
exit 1
fi
done
- name: Determine the release branch to use
run: |
if [[ ${RELEASE_VERSION} =~ beta ]] || [[ ${RELEASE_VERSION} =~ alpha ]]; then
export RELEASE_BRANCH=main
echo "RELEASE_BRANCH=${RELEASE_BRANCH}" >> ${GITHUB_ENV}
echo "This is a beta or alpha release, will use release branch ${RELEASE_BRANCH}"
else
export RELEASE_BRANCH=release-$(echo ${RELEASE_VERSION} | sed -E 's/^v([0-9]+)\.([0-9]+)\..*$/\1.\2/')
echo "RELEASE_BRANCH=${RELEASE_BRANCH}" >> ${GITHUB_ENV}
echo "This is not a beta or alpha release, will use release branch ${RELEASE_BRANCH}"
fi
- name: Create or checkout release branch
run: |
if git show-ref --verify --quiet "refs/remotes/origin/${RELEASE_BRANCH}"; then
echo "Branch ${RELEASE_BRANCH} already exists"
git checkout "${RELEASE_BRANCH}"
else
git checkout -b "${RELEASE_BRANCH}"
git push origin "${RELEASE_BRANCH}"
echo "Created branch ${RELEASE_BRANCH}"
fi
- name: Validate tag does not already exist
run: |
if [[ -n "$(git tag -l "${RELEASE_VERSION}")" ]]; then
echo "Tag ${RELEASE_VERSION} already exists, exiting"
exit 1
fi
- name: Create Release Tag
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git tag -a ${RELEASE_VERSION} -m ${RELEASE_VERSION}
git tag apis/${RELEASE_VERSION}
git tag test/${RELEASE_VERSION}
git tag pkg/hardwareutils/${RELEASE_VERSION}
git push origin ${RELEASE_VERSION}
git push origin apis/${RELEASE_VERSION}
git push origin test/${RELEASE_VERSION}
git push origin pkg/hardwareutils/${RELEASE_VERSION}
echo "Created tags ${RELEASE_VERSION}, apis/${RELEASE_VERSION}, pkg/hardwareutils/${RELEASE_VERSION}, and test/${RELEASE_VERSION}"
release:
name: create draft release
runs-on: ubuntu-latest
needs: push_release_tags
permissions:
contents: write
steps:
- name: Set env
run: echo "RELEASE_TAG=${RELEASE_TAG}" >> ${GITHUB_ENV}
env:
RELEASE_TAG: ${{needs.push_release_tags.outputs.release_tag}}
- name: checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ env.RELEASE_TAG }}
- name: Calculate go version
run: echo "go_version=$(make go-version)" >> ${GITHUB_ENV}
- name: Set up Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: ${{ env.go_version }}
- name: generate release artifacts
run: |
make release
- name: get release notes
run: |
curl -L "https://raw.githubusercontent.com/${{ github.repository }}/main/releasenotes/${{ env.RELEASE_TAG }}.md" \
-o "${{ env.RELEASE_TAG }}.md"
- name: Release
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
with:
draft: true
files: out/*
body_path: ${{ env.RELEASE_TAG }}.md
tag_name: ${{ env.RELEASE_TAG }}
build_keepalived:
permissions:
contents: read
needs: push_release_tags
name: Build keepalived container image
if: github.repository == 'metal3-io/utility-images'
uses: metal3-io/project-infra/.github/workflows/container-image-build.yml@main
with:
image-name: 'keepalived'
dockerfile-directory: keepalived
pushImage: true
ref: ${{ needs.push_release_tags.outputs.release_tag }}
secrets:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,21 @@ FakeIPA simulate the IPA by:
a queue of fake agents.
- Faking the sync/async commands needed by ironic to inspect,
clean and provision a node.

## Keepalived

Keepalived container used in Ironic deployments. Keepalived is used to
provide fix IP address for Ironic in such a manner that even after pivoting
operations the IP of Ironic stays persistent.

[Keeplaived documentation](https://www.keepalived.org/manpage.html)

Deployment configuration options:

- `CUSTOM_CONF_DIR` - when specified, the config files will be moved to the
specified directory and the variable substitution will happen there
- 'PROVISIONING_IP' - the fix IP provided by keepalived
- 'PROVISIONING_INTERFACE' - The name of the interface that will be used
to "host" the fixed IP (keepalived is used in a pod that is attached to
host network, thus the interface names are the same as the interface names
on the host)
157 changes: 157 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Releasing from from the utility-images repository

This document details the steps to create a release for a project in the
reporitory.

## Before making a release

Things you should check before making a release:

- Always check if there are project specific release instructions in
the project specific directory.
- Always check if there is a project specific verify-release.sh script in the
project's directory and if present run it and fix all issues highlighted
by the script prior to the release.

## Permissions

Creating a release requires repository `write` permissions for:

- Tag pushing
- Branch creation
- GitHub Release publishing

These permissions are implicit for the org admins and repository admins. Release
team member gets his/her permissions via `metal3-release-team` membership. This
GitHub team has the required permissions in each repository required to release
BMO. Adding person to the team gives him/her the necessary rights in all
relevant repositories in the organization. Individual persons should not be
given permissions directly.

## Process

BMO uses [semantic versioning](https://semver.org).

- Regular releases: `v0.x.y`
- Beta releases: `v0.x.y-beta.z`
- Release candidate releases: `v0.x.y-rc.z`

### Repository setup

Clone the repository: `git clone [email protected]:metal3-io/utility-images`

or if using existing repository, make sure origin is set to the fork and
upstream is set to `metal3-io`. Verify if your remote is set properly or not
by using following command `git remote -v`.

- Fetch the remote (`metal3-io`): `git fetch upstream`
This makes sure that all the tags are accessible.

### Creating Release Notes

- Switch to the main branch: `git checkout main`

- Create a new branch for the release notes**:
`git checkout -b release-notes-1.x.x origin/main`

- Generate the release notes: `RELEASE_TAG=v1.x.x make release-notes`
- Replace `v1.x.x` with the new release tag you're creating.
- This command generates the release notes here
`releasenotes/<RELEASE_TAG>.md` .

- Next step is to clean up the release note manually.
- If release is not a beta or release candidate, check for duplicates,
reverts, and incorrect classifications of PRs, and whatever release
creation tagged to be manually checked.
- For any superseded PRs (like same dependency uplifted multiple times, or
commit revertion) that provide no value to the release, move them to
Superseded section. This way the changes are acknowledged to be part of the
release, but not overwhelming the important changes contained by the
release.

- Commit your changes, push the new branch and create a pull request:
- The commit and PR title should be 🚀 Release v1.x.y:
-`git commit -S -s -m ":rocket: Release v1.x.x"`
-`git push -u origin release-notes-1.x.x`
- Important! The commit should only contain the release notes file, nothing
else, otherwise automation will not work.

- Ask maintainers and release team members to review your pull request.

Once PR is merged following GitHub actions are triggered:

- GitHub action `Create Release` runs following jobs:
- GitHub job `push_release_tags` will create and push the tags. This action
will also create release branch if its missing and release is `rc` or
minor.
- GitHub job `create draft release` creates draft release. Don't publish the
release until release tag is visible in. Running actions are visible on the
[Actions](https://github.com/metal3-io/utility-images/actions)
page, and draft release will be visible on top of the
[Releases](https://github.com/metal3-io/utility-images/releases).
If the release you're making is not a new major release, new minor release,
or a new patch release from the latest release branch, uncheck the box for
latest release. If it is a release candidate (RC) or a beta release,
tick pre-release box.
- GitHub jobs `build_keepalived` build release images with the
release tag, and push them to Quay. Make sure the release tags are visible in
Quay tags pages:
- [keepalived](https://quay.io/repository/metal3-io/keepalived?tab=tags)
If the new release tag is not available for any of the images, check if the
action has failed and retrigger as necessary.

### Release artifacts

We need to verify all release artifacts are correctly built or generated by the
release workflow. For a release, we should have the following artifacts:

There might be a project specific verify-release.sh in the project directory
that might automates the following checks:

Git tags pushed:

- Primary release tag: `v0.x.y`

Container images built and tagged at Quay registry:

- [keepalived:v0.x.y](https://quay.io/repository/metal3-io/keepalived?tab=tags)

Files included in the release page:

- Source code

### Make the release

After everything is checked out, hit the `Publish` button your GitHub draft
release!

## Post-release actions for new release branches

Some post-release actions are needed if new minor or major branch was created.

### Branch protection rules

Branch protection rules need to be applied to the new release branch. Copy the
settings after the previous release branch, with the exception of
`Required tests` selection. Required tests can only be selected after new
keywords are implemented in Jenkins JJB, and project-infra, and have been run at
least once in the PR targeting the branch in question. Branch protection rules
require user to have `admin` permissions in the repository.

### Update README.md and build badges

Update `README.md` with release specific information, both on `main` and in the
new `release-0.x` branch as necessary.

[Prior art](https://github.com/metal3-io/baremetal-operator/pull/1517)

In the `release-0.x` branch, update the build badges in the `README.md` to point
to correct Jenkins jobs, so the build statuses of the release branch are
visible.

[Prior art](https://github.com/metal3-io/baremetal-operator/pull/1518)

## Additional actions outside this repository

For that, please continue following the instructions provided in
[Metal3 release process](https://github.com/metal3-io/metal3-docs/blob/main/processes/releasing.md)
16 changes: 16 additions & 0 deletions keepalived/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Support FROM override
ARG BASE_IMAGE=ubuntu:22.04

FROM $BASE_IMAGE
ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get -y update && \
apt-get -y install keepalived && \
apt-get -y clean

COPY sample.keepalived.conf /etc/keepalived/keepalived.conf
COPY manage-keepalived.sh configure-nonroot.sh /bin/

RUN /bin/configure-nonroot.sh && rm /bin/configure-nonroot.sh

CMD ["/bin/bash", "/bin/manage-keepalived.sh"]
20 changes: 20 additions & 0 deletions keepalived/configure-nonroot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/bash

set -eux

# create nonroot image matching the keepalived manifest
NONROOT_USER="nonroot"
NONROOT_GROUP="nonroot"
NONROOT_UID=65532
NONROOT_GID=65532

# run as non-root, allow editing the keepalived.conf during startup
groupadd -g "${NONROOT_GID}" "${NONROOT_GROUP}"
useradd -u "${NONROOT_UID}" -g "${NONROOT_GID}" -m "${NONROOT_USER}"

mkdir -p /run/keepalived
chown -R root:"${NONROOT_GROUP}" /etc/keepalived /run/keepalived
chmod 2775 /etc/keepalived /run/keepalived
chmod 664 /etc/keepalived/keepalived.conf

setcap "cap_net_raw,cap_net_broadcast,cap_net_admin=+eip" /usr/sbin/keepalived
22 changes: 22 additions & 0 deletions keepalived/manage-keepalived.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/bash

set -eux
CUSTOM_CONF_DIR="${CUSTOM_CONF_DIR:-}"
KEEPALIVED_DEFAULT_CONF='/etc/keepalived/keepalived.conf'
if [[ -z "${CUSTOM_CONF_DIR}" ]]; then
KEEAPLIVED_CONF="${KEEPALIVED_DEFAULT_CONF}"
else
KEEAPLIVED_CONF="${KEEPALIVED_DEFAULT_CONF}/keepalived.conf"
cp "${KEEPALIVED_DEFAULT_CONF}" "${KEEAPLIVED_CONF}"

fi
export assignedIP="${PROVISIONING_IP}/32"
export interface="${PROVISIONING_INTERFACE}"

sed -i "s~INTERFACE~${interface}~g" "${KEEAPLIVED_CONF}"
sed -i "s~CHANGEIP~${assignedIP}~g" "${KEEAPLIVED_CONF}"

exec /usr/sbin/keepalived --dont-fork --log-console \
--pid='/run/keepalived/keepalived.pid' \
--vrrp_pid='/run/keepalived/vrrp.pid' \
--use-file="${KEEAPLIVED_CONF}"
Loading

0 comments on commit 307ec43

Please sign in to comment.