Feat: Implemented Swift for Openstack-Helm

Implements complete Swift object storage service for OpenStack-Helm with proxy and storage components, ring management, and full Kubernetes integration following openstack-helm patterns.

Features:
- Swift proxy deployment with configurable workers and middleware
- Storage daemonset with account/container/object servers
- Automated ring building and distribution
- Full networking: ClusterIP, NodePort, Ingress, service-ingress
- Keystone integration and service registration
- Helm test suite for functional validation
- Production-ready configuration management

Change-Id: I0e0abd5c0cdfc86d4a5a0cda5b8bcb4cc84983bf
Co-Authored-By: Vladimir Kozhukalov <kozhukalov@gmail.com>
Signed-off-by: James Bhatarai <jamesbhattarai14@gmail.com>
Signed-off-by: Vladimir Kozhukalov <kozhukalov@gmail.com>
This commit is contained in:
James Bhattarai
2026-01-20 13:42:32 +05:45
committed by Vladimir Kozhukalov
parent 0693074879
commit 74bd196bb8
41 changed files with 2616 additions and 0 deletions

View File

@@ -28,6 +28,7 @@ OpenStack charts options
placement
rally
skyline
swift
tacker
tempest
trove

31
swift/Chart.yaml Normal file
View File

@@ -0,0 +1,31 @@
# 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.
---
apiVersion: v2
appVersion: v1.0.0
name: swift
description: Openstack-Helm Swift
version: 2025.2.0
home: https://docs.openstack.org/swift/latest/
icon: https://www.openstack.org/themes/openstack/images/project-mascots/Swift/OpenStack_Project_Swift_vertical.jpg
sources:
- https://opendev.org/openstack/swift
- https://opendev.org/openstack/openstack-helm
maintainers:
- name: Openstack-Helm Authors
dependencies:
- name: helm-toolkit
repository: file://../helm-toolkit
version: ">= 0.1.0"
...

View File

@@ -0,0 +1,47 @@
{{/*
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.
*/}}
{{- define "swift.bin.account_start" }}
#!/bin/bash
set -ex
export HOME=/tmp
# Wait for ring files
echo "Waiting for account ring file..."
while [ ! -f /etc/swift/account.ring.gz ]; do
echo "Account ring file not found, waiting..."
sleep 5
done
echo "Account ring file found"
# Create required directories
mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock
# Set permissions
chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true
# Start account services
echo "Starting account services..."
swift-account-server /etc/swift/account-server.conf &
swift-account-auditor /etc/swift/account-server.conf &
swift-account-reaper /etc/swift/account-server.conf &
swift-account-replicator /etc/swift/account-server.conf &
echo "Swift account services started"
# Wait for any process to exit
wait
{{- end }}

View File

@@ -0,0 +1,41 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.bootstrap" }}
#!/bin/bash
set -ex
echo "Swift bootstrap started"
# Source credentials
export OS_AUTH_URL={{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }}
export OS_IDENTITY_API_VERSION=3
export OS_USERNAME={{ .Values.endpoints.identity.auth.admin.username }}
export OS_PASSWORD={{ .Values.endpoints.identity.auth.admin.password }}
export OS_PROJECT_NAME={{ .Values.endpoints.identity.auth.admin.project_name }}
export OS_USER_DOMAIN_NAME={{ .Values.endpoints.identity.auth.admin.user_domain_name }}
export OS_PROJECT_DOMAIN_NAME={{ .Values.endpoints.identity.auth.admin.project_domain_name }}
export OS_INTERFACE=internal
# Wait for Swift proxy to be ready
SWIFT_ENDPOINT={{ tuple "object_store" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }}
echo "Waiting for Swift endpoint at ${SWIFT_ENDPOINT}..."
count=0
while ! curl -s -o /dev/null -w '%{http_code}' "${SWIFT_ENDPOINT}/healthcheck" | grep -q "200"; do
if [ $count -ge 60 ]; then
echo "Timeout waiting for Swift endpoint"
exit 1
fi
echo "Waiting for Swift endpoint..."
sleep 5
count=$((count+1))
done
echo "Swift endpoint is healthy"
# Run any custom bootstrap script
{{ .Values.bootstrap.script | default "" }}
echo "Swift bootstrap complete"
{{- end }}

View File

@@ -0,0 +1,48 @@
{{/*
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.
*/}}
{{- define "swift.bin.container_start" }}
#!/bin/bash
set -ex
export HOME=/tmp
# Wait for ring files
echo "Waiting for container ring file..."
while [ ! -f /etc/swift/container.ring.gz ]; do
echo "Container ring file not found, waiting..."
sleep 5
done
echo "Container ring file found"
# Create required directories
mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock
# Set permissions
chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true
# Start container services
echo "Starting container services..."
swift-container-server /etc/swift/container-server.conf &
swift-container-auditor /etc/swift/container-server.conf &
swift-container-replicator /etc/swift/container-server.conf &
swift-container-updater /etc/swift/container-server.conf &
swift-container-sync /etc/swift/container-server.conf &
echo "Swift container services started"
# Wait for any process to exit
wait
{{- end }}

View File

@@ -0,0 +1,4 @@
#!/bin/bash
set -ex
{{ include "helm-toolkit.scripts.keystone_endpoints" . }}

View File

@@ -0,0 +1,4 @@
#!/bin/bash
set -ex
{{ include "helm-toolkit.scripts.keystone_service" . }}

View File

@@ -0,0 +1,4 @@
#!/bin/bash
set -ex
{{ include "helm-toolkit.scripts.keystone_user" . }}

View File

@@ -0,0 +1,52 @@
{{/*
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.
*/}}
{{- define "swift.bin.object_start" }}
#!/bin/bash
set -ex
export HOME=/tmp
# Wait for ring files
echo "Waiting for object ring file..."
while [ ! -f /etc/swift/object.ring.gz ]; do
echo "Object ring file not found, waiting..."
sleep 5
done
echo "Object ring file found"
# Create required directories
mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock
# Set permissions
chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true
# Start rsync daemon (object replication uses rsync)
echo "Starting rsync daemon..."
rsync --daemon --config=/etc/swift/rsyncd.conf
# Start object services
echo "Starting object services..."
swift-object-server /etc/swift/object-server.conf &
swift-object-auditor /etc/swift/object-server.conf &
swift-object-replicator /etc/swift/object-server.conf &
swift-object-updater /etc/swift/object-server.conf &
swift-object-reconstructor /etc/swift/object-server.conf 2>/dev/null &
echo "Swift object services started"
# Wait for any process to exit
wait
{{- end }}

View File

@@ -0,0 +1,54 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.proxy_start" }}
#!/bin/bash
set -ex
export HOME=/tmp
# Wait for ring files
echo "Waiting for ring files..."
while [ ! -f /etc/swift/account.ring.gz ] || [ ! -f /etc/swift/container.ring.gz ] || [ ! -f /etc/swift/object.ring.gz ]; do
echo "Ring files not found, waiting..."
sleep 5
done
echo "Ring files found"
ls -la /etc/swift/*.ring.gz
# Create required directories
mkdir -p /var/cache/swift /var/run/swift /var/log/swift
# Set permissions
chown -R swift:swift /etc/swift /var/cache/swift /var/run/swift /var/log/swift 2>/dev/null || true
# Resolve DNS and add to /etc/hosts to work around eventlet DNS issues
echo "Resolving service endpoints for eventlet compatibility..."
{{- $identityHost := tuple "identity" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}
{{- $cacheHost := tuple "oslo_cache" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}
# Resolve keystone
KEYSTONE_HOST="{{ $identityHost }}"
if [ -n "$KEYSTONE_HOST" ] && [ "$KEYSTONE_HOST" != "null" ]; then
KEYSTONE_IP=$(getent hosts "$KEYSTONE_HOST" | awk '{print $1}' | head -1)
if [ -n "$KEYSTONE_IP" ]; then
echo "$KEYSTONE_IP $KEYSTONE_HOST" >> /etc/hosts
echo "Added $KEYSTONE_IP $KEYSTONE_HOST to /etc/hosts"
fi
fi
# Resolve memcached
MEMCACHE_HOST="{{ $cacheHost }}"
if [ -n "$MEMCACHE_HOST" ] && [ "$MEMCACHE_HOST" != "null" ]; then
MEMCACHE_IP=$(getent hosts "$MEMCACHE_HOST" | awk '{print $1}' | head -1)
if [ -n "$MEMCACHE_IP" ]; then
echo "$MEMCACHE_IP $MEMCACHE_HOST" >> /etc/hosts
echo "Added $MEMCACHE_IP $MEMCACHE_HOST to /etc/hosts"
fi
fi
echo "Starting Swift Proxy Server..."
exec swift-proxy-server /etc/swift/proxy-server.conf --verbose
{{- end }}

View File

@@ -0,0 +1,84 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.ring_builder" }}
#!/bin/bash
set -ex
export HOME=/tmp
cd /etc/swift
PARTITION_POWER={{ .Values.ring.partition_power }}
REPLICAS={{ .Values.ring.replicas }}
MIN_PART_HOURS={{ .Values.ring.min_part_hours }}
# Get the storage service IP (for Kubernetes, use the storage service)
STORAGE_IP=${SWIFT_STORAGE_IP:-"127.0.0.1"}
echo "Building Swift rings with partition_power=$PARTITION_POWER, replicas=$REPLICAS, min_part_hours=$MIN_PART_HOURS"
echo "Storage IP: $STORAGE_IP"
# Create ring builder files if they don't exist
if [ ! -f account.builder ]; then
swift-ring-builder account.builder create $PARTITION_POWER $REPLICAS $MIN_PART_HOURS
fi
if [ ! -f container.builder ]; then
swift-ring-builder container.builder create $PARTITION_POWER $REPLICAS $MIN_PART_HOURS
fi
if [ ! -f object.builder ]; then
swift-ring-builder object.builder create $PARTITION_POWER $REPLICAS $MIN_PART_HOURS
fi
# Add devices from values
{{- range $index, $device := .Values.ring.devices }}
DEVICE_NAME="{{ $device.name }}"
DEVICE_WEIGHT="{{ $device.weight }}"
# Check if device already exists in account ring
if ! swift-ring-builder account.builder search --ip $STORAGE_IP --device $DEVICE_NAME 2>/dev/null | grep -q "$DEVICE_NAME"; then
swift-ring-builder account.builder add \
--region 1 --zone 1 --ip $STORAGE_IP --port 6202 \
--device $DEVICE_NAME --weight $DEVICE_WEIGHT || true
fi
# Check if device already exists in container ring
if ! swift-ring-builder container.builder search --ip $STORAGE_IP --device $DEVICE_NAME 2>/dev/null | grep -q "$DEVICE_NAME"; then
swift-ring-builder container.builder add \
--region 1 --zone 1 --ip $STORAGE_IP --port 6201 \
--device $DEVICE_NAME --weight $DEVICE_WEIGHT || true
fi
# Check if device already exists in object ring
if ! swift-ring-builder object.builder search --ip $STORAGE_IP --device $DEVICE_NAME 2>/dev/null | grep -q "$DEVICE_NAME"; then
swift-ring-builder object.builder add \
--region 1 --zone 1 --ip $STORAGE_IP --port 6200 \
--device $DEVICE_NAME --weight $DEVICE_WEIGHT || true
fi
{{- end }}
# Show ring status
echo "Account Ring:"
swift-ring-builder account.builder
echo "Container Ring:"
swift-ring-builder container.builder
echo "Object Ring:"
swift-ring-builder object.builder
# Rebalance rings
swift-ring-builder account.builder rebalance || true
swift-ring-builder container.builder rebalance || true
swift-ring-builder object.builder rebalance || true
# Copy ring files to shared location
cp /etc/swift/*.ring.gz /etc/swift-rings/ 2>/dev/null || true
cp /etc/swift/*.builder /etc/swift-rings/ 2>/dev/null || true
echo "Ring files created successfully"
ls -la /etc/swift/*.ring.gz /etc/swift/*.builder
{{- end }}

View File

@@ -0,0 +1,23 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.ring_copy" }}
#!/bin/bash
set -ex
echo "=== Swift Copy rings from shared storage ==="
for base in account container object; do
if [[ ! -f /etc/swift/${base}.ring.gz ]]; then
echo "Ring file /etc/swift/${base}.ring.gz not found in /etc/swift, attempting to copy from shared storage."
cp /etc/swift-rings/${base}.ring.gz /etc/swift/
echo "Copied ${base}.ring.gz from shared storage."
fi
if [[ ! -f /etc/swift/${base}.builder ]]; then
echo "Builder file /etc/swift/${base}.builder not found in /etc/swift, attempting to copy from shared storage."
cp /etc/swift-rings/${base}.builder /etc/swift/
echo "Copied ${base}.builder from shared storage."
fi
done
{{- end }}

View File

@@ -0,0 +1,84 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.storage_init" }}
#!/bin/bash
set -e
export HOME=/tmp
echo "=== Swift Storage Validation ==="
# Create swift user if it doesn't exist
getent group swift >/dev/null || groupadd -r swift
getent passwd swift >/dev/null || useradd -r -g swift -d /var/lib/swift -s /sbin/nologin swift
# Create required directories
mkdir -p /var/cache/swift /var/run/swift /var/lock /var/log/swift
# Validate storage devices from values.yaml
ERRORS=0
{{- range $device := .Values.ring.devices }}
DEVICE_NAME="{{ $device.name }}"
STOREDIR="/srv/node/${DEVICE_NAME}"
echo "Checking device: $DEVICE_NAME at $STOREDIR"
if [ ! -d "$STOREDIR" ]; then
echo "ERROR: Storage directory $STOREDIR does not exist!"
echo " Please mount your storage device to $STOREDIR before deploying Swift."
ERRORS=$((ERRORS + 1))
continue
fi
# Check if it's a mountpoint or at least writable
if ! touch "$STOREDIR/.swift_test" 2>/dev/null; then
echo "ERROR: Storage directory $STOREDIR is not writable!"
ERRORS=$((ERRORS + 1))
continue
fi
rm -f "$STOREDIR/.swift_test"
echo " ✓ $STOREDIR is valid and writable"
{{- end }}
if [ $ERRORS -gt 0 ]; then
echo ""
echo "=========================================="
echo "STORAGE VALIDATION FAILED"
echo "=========================================="
echo ""
echo "Swift requires pre-mounted storage devices."
echo "Please prepare your storage before deploying:"
echo ""
echo "For production (real disks):"
echo " mkfs.xfs /dev/sdX"
echo " mkdir -p /srv/node/sdX"
echo " mount /dev/sdX /srv/node/sdX"
echo ""
echo "For testing (loop devices):"
echo " truncate -s 1G /var/lib/swift/sdb1.img"
echo " losetup /dev/loop0 /var/lib/swift/sdb1.img"
echo " mkfs.xfs /dev/loop0"
echo " mkdir -p /srv/node/sdb1"
echo " mount /dev/loop0 /srv/node/sdb1"
echo ""
exit 1
fi
# Set permissions
chown -R swift:swift /srv/node /var/cache/swift /var/run/swift /var/lock /var/log/swift
chmod -R 755 /srv/node /var/cache/swift
echo ""
echo "=== Storage directories ==="
ls -la /srv/node/
echo ""
echo "=== Mount points ==="
mount | grep /srv/node || echo "(No dedicated mounts found - using directory storage)"
echo ""
echo "Storage validation complete - all devices ready"
{{- end }}

View File

@@ -0,0 +1,56 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.storage_start" }}
#!/bin/bash
set -ex
export HOME=/tmp
# Wait for ring files
echo "Waiting for ring files..."
while [ ! -f /etc/swift/account.ring.gz ] || [ ! -f /etc/swift/container.ring.gz ] || [ ! -f /etc/swift/object.ring.gz ]; do
echo "Ring files not found, waiting..."
sleep 5
done
echo "Ring files found"
ls -la /etc/swift/*.ring.gz
# Create required directories
mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock
# Set permissions
chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true
# Start rsync daemon
echo "Starting rsync daemon..."
rsync --daemon --config=/etc/swift/rsyncd.conf
# Start account services
echo "Starting account services..."
swift-account-server /etc/swift/account-server.conf &
swift-account-auditor /etc/swift/account-server.conf &
swift-account-reaper /etc/swift/account-server.conf &
swift-account-replicator /etc/swift/account-server.conf &
# Start container services
echo "Starting container services..."
swift-container-server /etc/swift/container-server.conf &
swift-container-auditor /etc/swift/container-server.conf &
swift-container-replicator /etc/swift/container-server.conf &
swift-container-updater /etc/swift/container-server.conf &
# Start object services
echo "Starting object services..."
swift-object-server /etc/swift/object-server.conf &
swift-object-auditor /etc/swift/object-server.conf &
swift-object-replicator /etc/swift/object-server.conf &
swift-object-updater /etc/swift/object-server.conf &
echo "All Swift storage services started"
# Wait for any process to exit
wait
{{- end }}

View File

@@ -0,0 +1,63 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "swift.bin.swift_test" }}
#!/bin/bash
set -ex
export HOME=/tmp
echo "===== Swift Functional Test ====="
# Get authentication token
echo "Getting Keystone token..."
TOKEN=$(openstack token issue -f value -c id)
echo "Token obtained successfully"
# Get Swift endpoint
SWIFT_URL=$(openstack endpoint list --service swift --interface public -f value -c URL | head -1)
echo "Swift URL: $SWIFT_URL"
# Test Swift stat
echo ""
echo "Testing swift stat..."
swift stat
# Create test container
CONTAINER="test-container-$(date +%s)"
echo ""
echo "Creating container: $CONTAINER"
swift post $CONTAINER
# List containers
echo ""
echo "Listing containers..."
swift list
# Upload a test file
echo "Hello from OpenStack Swift!" > /tmp/testfile.txt
echo ""
echo "Uploading test file..."
swift upload $CONTAINER /tmp/testfile.txt --object-name hello.txt
# List objects in container
echo ""
echo "Listing objects in $CONTAINER..."
swift list $CONTAINER
# Download and verify
echo ""
echo "Downloading test file..."
swift download $CONTAINER hello.txt -o /tmp/downloaded.txt
cat /tmp/downloaded.txt
# Cleanup
echo ""
echo "Cleaning up..."
swift delete $CONTAINER hello.txt
swift delete $CONTAINER
echo ""
echo "===== Swift Test Complete ====="
{{- end }}

View File

@@ -0,0 +1,28 @@
{{/*
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.
*/}}
{{/*
Certificates template requires proper TLS configuration in endpoints.
To enable, you must set:
- manifests.certificates: true
- secrets.tls.object_store.api.public: <secret-name>
- endpoints.object_store.host_fqdn_override.default.tls (with crt, key, ca)
*/}}
{{- if .Values.manifests.certificates -}}
{{- $secretName := .Values.secrets.tls.object_store.api.public -}}
{{- $fqdnOverride := index .Values.endpoints.object_store.host_fqdn_override "default" | default dict -}}
{{- if and $secretName (hasKey $fqdnOverride "tls") -}}
{{ dict "envAll" . "service" "object_store" "type" "public" | include "helm-toolkit.manifests.certificates" }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,70 @@
{{/*
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.
*/}}
{{- define "swift.configmap.bin" }}
{{- $envAll := . }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: swift-bin
labels:
{{ tuple $envAll "swift" "bin" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
data:
storage-init.sh: |
{{ include "swift.bin.storage_init" . | indent 4 }}
ring-builder.sh: |
{{ include "swift.bin.ring_builder" . | indent 4 }}
ring-copy.sh: |
{{ include "swift.bin.ring_copy" . | indent 4 }}
proxy-start.sh: |
{{ include "swift.bin.proxy_start" . | indent 4 }}
storage-start.sh: |
{{ include "swift.bin.storage_start" . | indent 4 }}
account-start.sh: |
{{ include "swift.bin.account_start" . | indent 4 }}
container-start.sh: |
{{ include "swift.bin.container_start" . | indent 4 }}
object-start.sh: |
{{ include "swift.bin.object_start" . | indent 4 }}
bootstrap.sh: |
{{ include "swift.bin.bootstrap" . | indent 4 }}
ks-service.sh: |
{{ tuple "bin/_ks-service.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
ks-endpoints.sh: |
{{ tuple "bin/_ks-endpoints.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
ks-user.sh: |
{{ tuple "bin/_ks-user.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
swift-test.sh: |
{{ include "swift.bin.swift_test" . | indent 4 }}
{{- if .Values.images.local_registry.active }}
image-repo-sync.sh: |
{{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }}
{{- end }}
{{- end }}
{{- if .Values.manifests.configmap_bin }}
{{- include "swift.configmap.bin" . }}
{{- end }}

View File

@@ -0,0 +1,116 @@
{{/*
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.
*/}}
{{- define "swift.configmap.etc" }}
{{- $envAll := . }}
{{- if empty .Values.conf.proxy_server.DEFAULT.swift_dir -}}
{{- $_ := set .Values.conf.proxy_server.DEFAULT "swift_dir" "/etc/swift" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:authtoken" "www_authenticate_uri") -}}
{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "www_authenticate_uri" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:authtoken" "auth_url") -}}
{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "auth_url" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:authtoken" "memcached_servers") -}}
{{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "memcached_servers" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:cache" "memcache_servers") -}}
{{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:cache") "memcache_servers" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:authtoken" "password") -}}
{{- $_ := .Values.endpoints.identity.auth.swift.password | set (index .Values.conf.proxy_server "filter:authtoken") "password" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:authtoken" "memcache_secret_key") -}}
{{- $_ := (default (randAlphaNum 64) .Values.endpoints.oslo_cache.auth.memcache_secret_key) | set (index .Values.conf.proxy_server "filter:authtoken") "memcache_secret_key" -}}
{{- end -}}
{{- if empty (index .Values.conf.proxy_server "filter:authtoken" "memcache_servers") -}}
{{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "memcache_servers" -}}
{{- end -}}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: swift-etc
labels:
{{ tuple $envAll "swift" "etc" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
data:
swift.conf: |
[swift-hash]
swift_hash_path_suffix = {{ .Values.conf.swift.swift_hash_path_suffix }}
swift_hash_path_prefix = {{ .Values.conf.swift.swift_hash_path_prefix }}
{{- range $policy := .Values.conf.swift.storage_policies }}
[storage-policy:{{ $policy.index }}]
name = {{ $policy.name }}
{{- if $policy.default }}
default = {{ $policy.default }}
{{- end }}
{{- if $policy.deprecated }}
deprecated = {{ $policy.deprecated }}
{{- end }}
{{- end }}
proxy-server.conf: |
{{ include "helm-toolkit.utils.to_ini" .Values.conf.proxy_server | indent 4 }}
account-server.conf: |
{{ include "helm-toolkit.utils.to_ini" .Values.conf.account_server | indent 4 }}
container-server.conf: |
{{ include "helm-toolkit.utils.to_ini" .Values.conf.container_server | indent 4 }}
object-server.conf: |
{{ include "helm-toolkit.utils.to_ini" .Values.conf.object_server | indent 4 }}
rsyncd.conf: |
uid = {{ .Values.conf.rsyncd.uid }}
gid = {{ .Values.conf.rsyncd.gid }}
log file = {{ .Values.conf.rsyncd.log_file }}
pid file = {{ .Values.conf.rsyncd.pid_file }}
address = {{ .Values.conf.rsyncd.address }}
[account]
max connections = {{ .Values.conf.rsyncd.account.max_connections }}
path = {{ .Values.conf.rsyncd.account.path }}
read only = {{ .Values.conf.rsyncd.account.read_only }}
lock file = {{ .Values.conf.rsyncd.account.lock_file }}
[container]
max connections = {{ .Values.conf.rsyncd.container.max_connections }}
path = {{ .Values.conf.rsyncd.container.path }}
read only = {{ .Values.conf.rsyncd.container.read_only }}
lock file = {{ .Values.conf.rsyncd.container.lock_file }}
[object]
max connections = {{ .Values.conf.rsyncd.object.max_connections }}
path = {{ .Values.conf.rsyncd.object.path }}
read only = {{ .Values.conf.rsyncd.object.read_only }}
lock file = {{ .Values.conf.rsyncd.object.lock_file }}
container-sync-realms.conf: |
{{ include "helm-toolkit.utils.to_ini" .Values.conf.swift.container_sync_realms | indent 4 }}
{{- end }}
{{- if .Values.manifests.configmap_etc }}
{{- include "swift.configmap.etc" . }}
{{- end }}

View File

@@ -0,0 +1,295 @@
{{/*
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.
*/}}
{{- if .Values.manifests.daemonset_storage }}
{{- $envAll := . }}
{{- $mounts_swift_storage := .Values.pod.mounts.swift_storage.swift_storage }}
{{- $mounts_swift_storage_init := .Values.pod.mounts.swift_storage.init_container }}
{{- $serviceAccountName := "swift-storage" }}
{{ tuple $envAll "storage" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: swift-storage
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
labels:
{{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
selector:
matchLabels:
{{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
{{ tuple $envAll "storage" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }}
template:
metadata:
labels:
{{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
{{ dict "envAll" $envAll "podName" "swift-storage" "containerNames" (list "swift-account" "swift-container" "swift-object" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }}
spec:
{{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
serviceAccountName: {{ $serviceAccountName }}
hostNetwork: true
hostPID: true
dnsPolicy: ClusterFirstWithHostNet
nodeSelector:
{{ .Values.labels.storage.node_selector_key }}: {{ .Values.labels.storage.node_selector_value }}
{{- if .Values.pod.tolerations.swift.enabled }}
{{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }}
{{- end }}
terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.storage.timeout | default 30 }}
initContainers:
{{ tuple $envAll "storage" $mounts_swift_storage_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
- name: storage-init
{{ tuple $envAll "swift_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_storage_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/storage-init.sh
terminationMessagePath: /tmp/termination-log
terminationMessagePolicy: File
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/storage-init.sh
subPath: storage-init.sh
readOnly: true
- name: srv-node
mountPath: /srv/node
- name: swift-data
mountPath: /var/lib/swift
{{- if .Values.manifests.pvc }}
- name: ring-copy
{{ tuple $envAll "swift_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_ring_copy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/ring-copy.sh
terminationMessagePath: /tmp/termination-log
terminationMessagePolicy: File
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/ring-copy.sh
subPath: ring-copy.sh
readOnly: true
- name: srv-node
mountPath: /srv/node
- name: swift-data
mountPath: /var/lib/swift
- name: swift-rings-host
mountPath: /etc/swift
- name: swift-rings
mountPath: {{ .Values.ring.shared_storage.mount_path }}
{{- end }}
containers:
- name: swift-account
{{ tuple $envAll "swift_account" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_account" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/account-start.sh
ports:
- name: account
containerPort: {{ .Values.conf.account_server.DEFAULT.bind_port }}
hostPort: {{ .Values.conf.account_server.DEFAULT.bind_port }}
readinessProbe:
exec:
command:
- /bin/bash
- -c
- "pgrep -f swift-account-server"
initialDelaySeconds: 30
periodSeconds: 15
livenessProbe:
exec:
command:
- /bin/bash
- -c
- "pgrep -f swift-account-server"
initialDelaySeconds: 30
periodSeconds: 30
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/account-start.sh
subPath: account-start.sh
readOnly: true
- name: swift-etc
mountPath: /etc/swift/swift.conf
subPath: swift.conf
readOnly: true
- name: swift-etc
mountPath: /etc/swift/account-server.conf
subPath: account-server.conf
readOnly: true
- name: srv-node
mountPath: /srv/node
- name: swift-rings-host
mountPath: /etc/swift/account.ring.gz
subPath: account.ring.gz
readOnly: true
{{- if $mounts_swift_storage.volumeMounts }}{{ toYaml $mounts_swift_storage.volumeMounts | indent 12 }}{{ end }}
- name: swift-container
{{ tuple $envAll "swift_container" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_container" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/container-start.sh
ports:
- name: container
containerPort: {{ .Values.conf.container_server.DEFAULT.bind_port }}
hostPort: {{ .Values.conf.container_server.DEFAULT.bind_port }}
readinessProbe:
exec:
command:
- /bin/bash
- -c
- "pgrep -f swift-container-server"
initialDelaySeconds: 30
periodSeconds: 15
livenessProbe:
exec:
command:
- /bin/bash
- -c
- "pgrep -f swift-container-server"
initialDelaySeconds: 30
periodSeconds: 30
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/container-start.sh
subPath: container-start.sh
readOnly: true
- name: swift-etc
mountPath: /etc/swift/swift.conf
subPath: swift.conf
readOnly: true
- name: swift-etc
mountPath: /etc/swift/container-server.conf
subPath: container-server.conf
readOnly: true
- name: srv-node
mountPath: /srv/node
- name: swift-rings-host
mountPath: /etc/swift/container.ring.gz
subPath: container.ring.gz
readOnly: true
{{- if $mounts_swift_storage.volumeMounts }}{{ toYaml $mounts_swift_storage.volumeMounts | indent 12 }}{{ end }}
- name: swift-object
{{ tuple $envAll "swift_object" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_object" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/object-start.sh
ports:
- name: object
containerPort: {{ .Values.conf.object_server.DEFAULT.bind_port }}
hostPort: {{ .Values.conf.object_server.DEFAULT.bind_port }}
- name: rsync
containerPort: 873
hostPort: 873
readinessProbe:
exec:
command:
- /bin/bash
- -c
- "pgrep -f swift-object-server"
initialDelaySeconds: 30
periodSeconds: 15
livenessProbe:
exec:
command:
- /bin/bash
- -c
- "pgrep -f swift-object-server && pgrep -f rsync"
initialDelaySeconds: 30
periodSeconds: 30
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/object-start.sh
subPath: object-start.sh
readOnly: true
- name: swift-etc
mountPath: /etc/swift/swift.conf
subPath: swift.conf
readOnly: true
- name: swift-etc
mountPath: /etc/swift/object-server.conf
subPath: object-server.conf
readOnly: true
- name: swift-etc
mountPath: /etc/swift/rsyncd.conf
subPath: rsyncd.conf
readOnly: true
- name: srv-node
mountPath: /srv/node
- name: swift-rings-host
mountPath: /etc/swift/object.ring.gz
subPath: object.ring.gz
readOnly: true
{{- if $mounts_swift_storage.volumeMounts }}{{ toYaml $mounts_swift_storage.volumeMounts | indent 12 }}{{ end }}
volumes:
- name: pod-tmp
emptyDir: {}
- name: swift-bin
configMap:
name: swift-bin
defaultMode: 0555
- name: swift-etc
configMap:
name: swift-etc
defaultMode: 0444
- name: srv-node
hostPath:
path: /srv/node
type: DirectoryOrCreate
- name: swift-data
hostPath:
path: /var/lib/swift
type: DirectoryOrCreate
- name: swift-rings-host
hostPath:
path: /etc/swift
type: DirectoryOrCreate
{{- if .Values.manifests.pvc }}
- name: swift-rings
persistentVolumeClaim:
claimName: {{ .Values.ring.shared_storage.name }}
{{- end }}
{{- if $mounts_swift_storage.volumes }}{{ toYaml $mounts_swift_storage.volumes | indent 8 }}{{ end }}
{{- end }}

View File

@@ -0,0 +1,138 @@
{{/*
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.
*/}}
{{- if .Values.manifests.deployment_proxy }}
{{- $envAll := . }}
{{- $mounts_swift_proxy := .Values.pod.mounts.swift_proxy.swift_proxy }}
{{- $mounts_swift_proxy_init := .Values.pod.mounts.swift_proxy.init_container }}
{{- $serviceAccountName := "swift-proxy" }}
{{ tuple $envAll "proxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: swift-proxy
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
labels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
replicas: {{ .Values.pod.replicas.proxy }}
selector:
matchLabels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
{{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }}
template:
metadata:
labels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
{{ dict "envAll" $envAll "podName" "swift-proxy" "containerNames" (list "swift-proxy" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }}
spec:
{{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
serviceAccountName: {{ $serviceAccountName }}
dnsPolicy: ClusterFirst
dnsConfig:
options:
- name: ndots
value: "2"
- name: single-request-reopen
affinity:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
nodeSelector:
{{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }}
{{- if .Values.pod.tolerations.swift.enabled }}
{{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }}
{{- end }}
terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.proxy.timeout | default 30 }}
initContainers:
{{ tuple $envAll "proxy" $mounts_swift_proxy_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
containers:
- name: swift-proxy
{{ tuple $envAll "swift_proxy" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/proxy-start.sh
ports:
- name: swift-api
containerPort: {{ .Values.conf.proxy_server.DEFAULT.bind_port }}
readinessProbe:
httpGet:
path: /healthcheck
port: {{ .Values.conf.proxy_server.DEFAULT.bind_port }}
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthcheck
port: {{ .Values.conf.proxy_server.DEFAULT.bind_port }}
initialDelaySeconds: 30
periodSeconds: 30
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/proxy-start.sh
subPath: proxy-start.sh
readOnly: true
- name: swift-etc
mountPath: /etc/swift/swift.conf
subPath: swift.conf
readOnly: true
- name: swift-etc
mountPath: /etc/swift/proxy-server.conf
subPath: proxy-server.conf
readOnly: true
- name: swift-etc
mountPath: /etc/swift/container-sync-realms.conf
subPath: container-sync-realms.conf
readOnly: true
- name: swift-rings
mountPath: /etc/swift/account.ring.gz
subPath: account.ring.gz
readOnly: true
- name: swift-rings
mountPath: /etc/swift/container.ring.gz
subPath: container.ring.gz
readOnly: true
- name: swift-rings
mountPath: /etc/swift/object.ring.gz
subPath: object.ring.gz
readOnly: true
{{- if $mounts_swift_proxy.volumeMounts }}{{ toYaml $mounts_swift_proxy.volumeMounts | indent 12 }}{{ end }}
volumes:
- name: pod-tmp
emptyDir: {}
- name: swift-bin
configMap:
name: swift-bin
defaultMode: 0555
- name: swift-etc
configMap:
name: swift-etc
defaultMode: 0444
- name: swift-rings
hostPath:
path: /etc/swift
type: DirectoryOrCreate
{{- if $mounts_swift_proxy.volumes }}{{ toYaml $mounts_swift_proxy.volumes | indent 8 }}{{ end }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{/*
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.
*/}}
{{- if and .Values.manifests.ingress_proxy .Values.network.proxy.ingress.public }}
{{- $envAll := . }}
{{- $ingressOpts := dict "envAll" $envAll "backendService" "proxy" "backendServiceType" "object_store" "backendPort" "swift-api" -}}
{{- $secretName := $envAll.Values.secrets.tls.object_store.api.public -}}
{{- if and .Values.manifests.certificates $secretName -}}
{{- $fqdnOverride := index .Values.endpoints.object_store.host_fqdn_override "default" | default dict -}}
{{- if and $fqdnOverride (hasKey $fqdnOverride "tls") -}}
{{- $tlsConfig := index $fqdnOverride "tls" | default dict -}}
{{- if and $tlsConfig (hasKey $tlsConfig "issuerRef") -}}
{{- $issuerRef := index $tlsConfig "issuerRef" | default dict -}}
{{- if and $issuerRef (hasKey $issuerRef "name") -}}
{{- $_ := set $ingressOpts "certIssuer" $issuerRef.name -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{ $ingressOpts | include "helm-toolkit.manifests.ingress" }}
{{- end }}

View File

@@ -0,0 +1,72 @@
{{/*
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.
*/}}
{{- if .Values.manifests.job_bootstrap }}
{{- $envAll := . }}
{{- $serviceAccountName := "swift-bootstrap" }}
{{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: swift-bootstrap
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
labels:
{{ tuple $envAll "swift" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
template:
metadata:
labels:
{{ tuple $envAll "swift" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
spec:
{{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
serviceAccountName: {{ $serviceAccountName }}
restartPolicy: OnFailure
nodeSelector:
{{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }}
{{- if .Values.pod.tolerations.swift.enabled }}
{{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }}
{{- end }}
initContainers:
{{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
containers:
- name: swift-bootstrap
{{ tuple $envAll "bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- /bin/bash
- -c
- /tmp/bootstrap.sh
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/bootstrap.sh
subPath: bootstrap.sh
readOnly: true
env:
{{- with $env := dict "ksUserSecret" "swift-keystone-admin" "useCA" .Values.manifests.certificates }}
{{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }}
{{- end }}
volumes:
- name: pod-tmp
emptyDir: {}
- name: swift-bin
configMap:
name: swift-bin
defaultMode: 0555
{{- end }}

View File

@@ -0,0 +1,24 @@
{{/*
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.
*/}}
{{- define "metadata.annotations.job.repo_sync" }}
helm.sh/hook: post-install,post-upgrade
{{- end }}
{{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }}
{{- $imageRepoSyncJob := dict "envAll" . "serviceName" "swift" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}}
{{- if .Values.pod.tolerations.swift.enabled -}}
{{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}}
{{- end -}}
{{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }}
{{- end }}

View File

@@ -0,0 +1,16 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "metadata.annotations.job.ks_endpoints" }}
helm.sh/hook: post-install,post-upgrade
helm.sh/hook-weight: "-2"
{{- end }}
{{- if .Values.manifests.job_ks_endpoints }}
{{- $ksServiceJob := dict "envAll" . "serviceName" "swift" "serviceTypes" ( tuple "object-store" ) -}}
{{- if .Values.helm3_hook }}
{{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }}
{{- end }}
{{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }}
{{- end }}

View File

@@ -0,0 +1,16 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "metadata.annotations.job.ks_service" }}
helm.sh/hook: post-install,post-upgrade
helm.sh/hook-weight: "-3"
{{- end }}
{{- if .Values.manifests.job_ks_service }}
{{- $ksServiceJob := dict "envAll" . "serviceName" "swift" "serviceTypes" ( tuple "object-store" ) -}}
{{- if .Values.helm3_hook }}
{{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }}
{{- end }}
{{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }}
{{- end }}

View File

@@ -0,0 +1,16 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- define "metadata.annotations.job.ks_user" }}
helm.sh/hook: post-install,post-upgrade
helm.sh/hook-weight: "-1"
{{- end }}
{{- if .Values.manifests.job_ks_user }}
{{- $ksUserJob := dict "envAll" . "serviceName" "swift" -}}
{{- if .Values.helm3_hook }}
{{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }}
{{- end }}
{{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }}
{{- end }}

View File

@@ -0,0 +1,96 @@
{{/*
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.
*/}}
{{- if .Values.manifests.job_ring_builder }}
{{- $envAll := . }}
{{- $serviceAccountName := "swift-ring-builder" }}
{{ tuple $envAll "ring_builder" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: swift-ring-builder
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
labels:
{{ tuple $envAll "swift" "ring-builder" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
template:
metadata:
labels:
{{ tuple $envAll "swift" "ring-builder" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
spec:
{{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
serviceAccountName: {{ $serviceAccountName }}
restartPolicy: OnFailure
nodeSelector:
{{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }}
{{- if .Values.pod.tolerations.swift.enabled }}
{{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }}
{{- end }}
initContainers:
{{ tuple $envAll "ring_builder" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
containers:
- name: ring-builder
{{ tuple $envAll "swift_ring_builder" | include "helm-toolkit.snippets.image" | indent 10 }}
{{ tuple $envAll $envAll.Values.pod.resources.jobs.ring_builder | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "swift" "container" "swift_ring_builder" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
env:
- name: SWIFT_STORAGE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
command:
- /bin/bash
- -c
- /tmp/ring-builder.sh
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/ring-builder.sh
subPath: ring-builder.sh
readOnly: true
- name: swift-rings-host
mountPath: /etc/swift
- name: swift-etc
mountPath: /etc/swift/swift.conf
subPath: swift.conf
readOnly: true
{{- if .Values.manifests.pvc }}
- name: swift-rings
mountPath: {{ .Values.ring.shared_storage.mount_path }}
{{- end }}
volumes:
- name: pod-tmp
emptyDir: {}
- name: swift-bin
configMap:
name: swift-bin
defaultMode: 0555
- name: swift-etc
configMap:
name: swift-etc
defaultMode: 0444
- name: swift-rings-host
hostPath:
path: /etc/swift
type: DirectoryOrCreate
{{- if .Values.manifests.pvc }}
- name: swift-rings
persistentVolumeClaim:
claimName: {{ .Values.ring.shared_storage.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,35 @@
{{/*
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.
*/}}
{{- if .Values.manifests.network_policy }}
{{- $envAll := . }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: swift-network-policy
labels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
podSelector:
matchLabels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
{{ toYaml .Values.network_policy.swift.ingress | indent 4 }}
egress:
{{ toYaml .Values.network_policy.swift.egress | indent 4 }}
{{- end }}

View File

@@ -0,0 +1,29 @@
{{/*
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.
*/}}
{{- if .Values.manifests.pdb_proxy }}
{{- $envAll := . }}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: swift-proxy-pdb
labels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
minAvailable: {{ .Values.pod.pdb.proxy.minAvailable | default 1 }}
selector:
matchLabels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
{{- end }}

View File

@@ -0,0 +1,29 @@
{{/*
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.
*/}}
{{- if .Values.manifests.pdb_storage }}
{{- $envAll := . }}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: swift-storage-pdb
labels:
{{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
minAvailable: {{ .Values.pod.pdb.storage.minAvailable | default 1 }}
selector:
matchLabels:
{{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
{{- end }}

View File

@@ -0,0 +1,55 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- if .Values.manifests.pod_test }}
{{- $envAll := . }}
{{- $serviceAccountName := "swift-test" }}
{{ tuple $envAll "test" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
---
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-test"
annotations:
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
"helm.sh/hook": test-success
labels:
{{ tuple $envAll "swift" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
serviceAccountName: {{ $serviceAccountName }}
nodeSelector:
{{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }}
restartPolicy: Never
initContainers:
{{ tuple $envAll "test" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }}
containers:
- name: swift-test
image: {{ .Values.images.tags.test }}
imagePullPolicy: {{ .Values.images.pull_policy }}
command:
- /bin/bash
- -c
- /tmp/swift-test.sh
volumeMounts:
- name: pod-tmp
mountPath: /tmp
- name: swift-bin
mountPath: /tmp/swift-test.sh
subPath: swift-test.sh
readOnly: true
env:
{{- with $env := dict "ksUserSecret" "swift-keystone-user" "useCA" .Values.manifests.certificates }}
{{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }}
{{- end }}
- name: SWIFT_TEST_CONTAINER
value: "test-container-{{ randAlphaNum 8 | lower }}"
volumes:
- name: pod-tmp
emptyDir: {}
- name: swift-bin
configMap:
name: swift-bin
defaultMode: 0555
{{- end }}

35
swift/templates/pvc.yaml Normal file
View File

@@ -0,0 +1,35 @@
{{/*
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.
*/}}
{{ define "swift.pvc" }}
{{- $name := index . 0 }}
{{- $size := index . 1 }}
{{- $storageClassName := index . 2 }}
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ $name }}
spec:
accessModes:
- "ReadWriteMany"
resources:
requests:
storage: {{ $size }}
storageClassName: {{ $storageClassName }}
{{- end }}
{{- if .Values.manifests.pvc }}
{{ tuple .Values.ring.shared_storage.name .Values.ring.shared_storage.size .Values.ring.shared_storage.storageClassName | include "swift.pvc" }}
{{- end }}

View File

@@ -0,0 +1,20 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
*/}}
{{- if .Values.manifests.secret_keystone }}
{{- $envAll := . }}
{{- range $key1, $userClass := tuple "admin" "swift" }}
{{- $secretName := index $envAll.Values.secrets.identity $userClass }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
annotations:
{{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }}
type: Opaque
data:
{{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,18 @@
{{/*
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.
*/}}
{{- if and .Values.manifests.service_ingress_proxy .Values.network.proxy.ingress.public }}
{{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "object_store" -}}
{{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }}
{{- end }}

View File

@@ -0,0 +1,42 @@
{{/*
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.
*/}}
{{- if .Values.manifests.service_proxy }}
{{- $envAll := . }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ tuple "object_store" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
labels:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
spec:
{{- if .Values.network.proxy.node_port.enabled }}
type: NodePort
{{- if .Values.network.proxy.external_policy_local }}
externalTrafficPolicy: Local
{{- end }}
{{- else }}
type: ClusterIP
{{- end }}
selector:
{{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
ports:
- name: swift-api
port: {{ .Values.endpoints.object_store.port.api.default }}
targetPort: {{ .Values.conf.proxy_server.DEFAULT.bind_port }}
{{- if .Values.network.proxy.node_port.enabled }}
nodePort: {{ .Values.network.proxy.node_port.port }}
{{- end }}
{{- end }}

735
swift/values.yaml Normal file
View File

@@ -0,0 +1,735 @@
# 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.
---
release_group: null
# Helm3 hook for job ordering
helm3_hook: true
labels:
api:
node_selector_key: openstack-control-plane
node_selector_value: enabled
storage:
node_selector_key: openstack-control-plane
node_selector_value: enabled
job:
node_selector_key: openstack-control-plane
node_selector_value: enabled
test:
node_selector_key: openstack-control-plane
node_selector_value: enabled
images:
tags:
bootstrap: quay.io/airshipit/swift:2025.2-ubuntu_noble
test: quay.io/airshipit/swift:2025.2-ubuntu_noble
dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy
swift_proxy: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_account: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_container: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_object: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_storage: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_storage_init: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_ring_builder: quay.io/airshipit/swift:2025.2-ubuntu_noble
ks_user: quay.io/airshipit/heat:2025.2-ubuntu_noble
ks_service: quay.io/airshipit/heat:2025.2-ubuntu_noble
ks_endpoints: quay.io/airshipit/heat:2025.2-ubuntu_noble
image_repo_sync: docker.io/docker:17.07.0
pull_policy: Always
local_registry:
active: false
exclude:
- dep_check
- image_repo_sync
pod:
security_context:
swift:
pod:
runAsUser: 0
container:
swift_proxy:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
swift_account:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
swift_container:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
swift_object:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
swift_storage_init:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
swift_ring_builder:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
swift_ring_copy:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
privileged: true
bootstrap:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: false
affinity:
anti:
type:
default: preferredDuringSchedulingIgnoredDuringExecution
topologyKey:
default: kubernetes.io/hostname
replicas:
# Number of proxy replicas (Deployment)
proxy: 3
# Note: storage uses DaemonSet, so this is not used.
# Storage pods run on all nodes matching the storage node selector.
lifecycle:
upgrades:
deployments:
revision_history: 3
pod_replacement_strategy: RollingUpdate
rolling_update:
max_unavailable: 1
max_surge: 3
daemonsets:
storage:
enabled: true
min_ready_seconds: 0
max_unavailable: 1
termination_grace_period:
proxy:
timeout: 30
storage:
timeout: 30
resources:
enabled: true
proxy:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
storage:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
jobs:
bootstrap:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
ring_builder:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
ks_user:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
ks_service:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
ks_endpoints:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
tests:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
image_repo_sync:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "2000m"
tolerations:
swift:
enabled: false
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
mounts:
swift_proxy:
init_container: null
swift_proxy:
volumeMounts:
volumes:
swift_storage:
init_container: null
swift_storage:
volumeMounts:
volumes:
pdb:
proxy:
minAvailable: 1
storage:
minAvailable: 1
network_policy:
swift:
ingress:
- {}
egress:
- {}
network:
proxy:
ingress:
public: true
classes:
namespace: "ingress-openstack"
cluster: "ingress-cluster"
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: "0"
external_policy_local: false
node_port:
enabled: false
port: 30808
bootstrap:
enabled: false
script: null
# Ring Configuration
# partition_power: 2^N partitions (10=1024, 14=16384)
# replicas: number of data copies (production=3, minimum for HA)
# min_part_hours: minimum hours between partition moves (production=24)
# devices: list of storage devices used by Swift
# - name: device name (must match mountpoint under /srv/node/)
# - weight: relative capacity weight (100 = standard, higher = more data)
#
# IMPORTANT: Devices must be pre-mounted before deploying Swift.
# For production: mount real block devices (e.g., /dev/sdb1 -> /srv/node/sdb1)
# For development: use loop devices or directories
#
# Example production config:
# devices:
# - name: sdb1
# weight: 100
# - name: sdc1
# weight: 100
#
ring:
partition_power: 10
replicas: 3
min_part_hours: 24
devices: []
# Example:
# devices:
# - name: sdb1
# weight: 100
# - name: sdb2
# weight: 100
shared_storage:
name: swift-shared-storage
storageClassName: nfs-provisioner
size: 1Gi
mount_path: "/etc/swift-rings"
conf:
swift:
swift_hash_path_suffix: CHANGE_ME_SUFFIX
swift_hash_path_prefix: CHANGE_ME_PREFIX
storage_policies:
- name: Policy-0
index: 0
default: "yes"
container_sync_realms:
DEFAULT:
mtime_check_interval: 300
proxy_server:
DEFAULT:
bind_ip: 0.0.0.0
bind_port: 8080
workers: 2
user: swift
swift_dir: /etc/swift
log_level: INFO
log_name: proxy-server
log_facility:
log_address:
loggers:
keys: root,swift
handlers:
keys: console
formatters:
keys: simple
logger_root:
level: INFO
handlers: console
logger_swift:
level: INFO
handlers: console
qualname: swift
propagate: 0
handler_console:
class: StreamHandler
level: INFO
formatter: simple
args: (sys.stdout,)
formatter_simple:
format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s"
datefmt: "%Y-%m-%d %H:%M:%S"
"pipeline:main":
pipeline: catch_errors gatekeeper healthcheck proxy-logging cache listing_formats container_sync bulk ratelimit authtoken keystoneauth copy container-quotas account-quotas slo dlo versioned_writes symlink proxy-logging proxy-server
"app:proxy-server":
use: egg:swift#proxy
account_autocreate: "true"
allow_account_management: "true"
"filter:authtoken":
paste.filter_factory: keystonemiddleware.auth_token:filter_factory
delay_auth_decision: "True"
www_authenticate_uri: null
auth_url: null
auth_type: password
memcached_servers: null
memcache_security_strategy: ENCRYPT
memcache_secret_key: null
username: swift
password: null
project_name: service
user_domain_name: default
project_domain_name: default
service_token_roles_required: "true"
"filter:keystoneauth":
use: egg:swift#keystoneauth
operator_roles: admin,member,swiftoperator
reseller_prefix: AUTH_
reseller_admin_role: ResellerAdmin
"filter:healthcheck":
use: egg:swift#healthcheck
"filter:cache":
use: egg:swift#memcache
memcache_servers: null
"filter:account-quotas":
use: egg:swift#account_quotas
"filter:container-quotas":
use: egg:swift#container_quotas
"filter:proxy-logging":
use: egg:swift#proxy_logging
"filter:bulk":
use: egg:swift#bulk
"filter:slo":
use: egg:swift#slo
"filter:dlo":
use: egg:swift#dlo
"filter:versioned_writes":
use: egg:swift#versioned_writes
allow_versioned_writes: "true"
"filter:copy":
use: egg:swift#copy
"filter:container_sync":
use: egg:swift#container_sync
"filter:ratelimit":
use: egg:swift#ratelimit
"filter:catch_errors":
use: egg:swift#catch_errors
"filter:gatekeeper":
use: egg:swift#gatekeeper
"filter:listing_formats":
use: egg:swift#listing_formats
"filter:symlink":
use: egg:swift#symlink
account_server:
DEFAULT:
bind_ip: 0.0.0.0
bind_port: 6202
workers: 2
user: swift
swift_dir: /etc/swift
devices: /srv/node
mount_check: "true"
log_level: INFO
log_name: account-server
log_facility:
log_address:
loggers:
keys: root,swift
handlers:
keys: console
formatters:
keys: simple
logger_root:
level: INFO
handlers: console
logger_swift:
level: INFO
handlers: console
qualname: swift
propagate: 0
handler_console:
class: StreamHandler
level: INFO
formatter: simple
args: (sys.stdout,)
formatter_simple:
format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s"
datefmt: "%Y-%m-%d %H:%M:%S"
"pipeline:main":
pipeline: healthcheck recon account-server
"app:account-server":
use: egg:swift#account
"filter:healthcheck":
use: egg:swift#healthcheck
"filter:recon":
use: egg:swift#recon
recon_cache_path: /var/cache/swift
"account-replicator":
concurrency: 2
"account-auditor": {}
"account-reaper": {}
container_server:
DEFAULT:
bind_ip: 0.0.0.0
bind_port: 6201
workers: 2
user: swift
swift_dir: /etc/swift
devices: /srv/node
mount_check: "true"
log_level: INFO
log_name: container-server
log_facility:
log_address:
loggers:
keys: root,swift
handlers:
keys: console
formatters:
keys: simple
logger_root:
level: INFO
handlers: console
logger_swift:
level: INFO
handlers: console
qualname: swift
propagate: 0
handler_console:
class: StreamHandler
level: INFO
formatter: simple
args: (sys.stdout,)
formatter_simple:
format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s"
datefmt: "%Y-%m-%d %H:%M:%S"
"pipeline:main":
pipeline: healthcheck recon container-server
"app:container-server":
use: egg:swift#container
"filter:healthcheck":
use: egg:swift#healthcheck
"filter:recon":
use: egg:swift#recon
recon_cache_path: /var/cache/swift
"container-replicator":
concurrency: 2
"container-updater":
concurrency: 2
"container-auditor": {}
"container-sync": {}
object_server:
DEFAULT:
bind_ip: 0.0.0.0
bind_port: 6200
workers: 2
user: swift
swift_dir: /etc/swift
devices: /srv/node
mount_check: "true"
log_level: INFO
log_name: object-server
log_facility:
log_address:
loggers:
keys: root,swift
handlers:
keys: console
formatters:
keys: simple
logger_root:
level: INFO
handlers: console
logger_swift:
level: INFO
handlers: console
qualname: swift
propagate: 0
handler_console:
class: StreamHandler
level: INFO
formatter: simple
args: (sys.stdout,)
formatter_simple:
format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s"
datefmt: "%Y-%m-%d %H:%M:%S"
"pipeline:main":
pipeline: healthcheck recon object-server
"app:object-server":
use: egg:swift#object
"filter:healthcheck":
use: egg:swift#healthcheck
"filter:recon":
use: egg:swift#recon
recon_cache_path: /var/cache/swift
recon_lock_path: /var/lock
"object-replicator":
concurrency: 2
"object-updater":
concurrency: 2
"object-auditor": {}
rsyncd:
uid: swift
gid: swift
log_file: /var/log/rsyncd.log
pid_file: /var/run/rsyncd.pid
address: 0.0.0.0
account:
max_connections: 4
path: /srv/node/
read_only: "False"
lock_file: /var/lock/account.lock
container:
max_connections: 4
path: /srv/node/
read_only: "False"
lock_file: /var/lock/container.lock
object:
max_connections: 4
path: /srv/node/
read_only: "False"
lock_file: /var/lock/object.lock
secrets:
identity:
admin: swift-keystone-admin
swift: swift-keystone-user
tls:
object_store:
api:
public: swift-tls-public
dependencies:
dynamic:
common:
local_image_registry:
jobs:
- swift-image-repo-sync
services:
- endpoint: node
service: local_image_registry
static:
ring_builder:
jobs: null
services: null
# storage_init:
# jobs:
# - swift-ring-builder
# services: null
storage:
# jobs:
# - swift-storage-init
services: null
proxy:
daemonset:
- swift-storage
# jobs:
# - swift-storage-init
services:
- endpoint: internal
service: identity
- endpoint: internal
service: oslo_cache
ks_endpoints:
jobs:
- swift-ks-service
services:
- endpoint: internal
service: identity
ks_service:
services:
- endpoint: internal
service: identity
ks_user:
services:
- endpoint: internal
service: identity
bootstrap:
jobs:
- swift-ks-user
- swift-ks-endpoints
services:
- endpoint: internal
service: identity
- endpoint: internal
service: object_store
tests:
services:
- endpoint: internal
service: identity
- endpoint: internal
service: object_store
endpoints:
cluster_domain_suffix: cluster.local
local_image_registry:
name: docker-registry
namespace: docker-registry
hosts:
default: localhost
internal: docker-registry
node: localhost
host_fqdn_override:
default: null
port:
registry:
node: 5000
identity:
name: keystone
auth:
admin:
region_name: RegionOne
username: admin
password: password
project_name: admin
user_domain_name: default
project_domain_name: default
swift:
role: admin
region_name: RegionOne
username: swift
password: password
project_name: service
user_domain_name: default
project_domain_name: default
hosts:
default: keystone
internal: keystone-api
host_fqdn_override:
default: null
path:
default: /v3
scheme:
default: http
port:
api:
default: 80
internal: 5000
object_store:
name: swift
hosts:
default: swift-proxy
public: swift
host_fqdn_override:
default: null
# NOTE: This chart supports TLS for FQDN over-ridden public
# endpoints using the following format:
# public:
# host: swift.example.com
# tls:
# crt: |
# <certificate content>
# key: |
# <key content>
# ca: |
# <ca certificate content>
path:
default: /v1/AUTH_%(tenant_id)s
scheme:
default: http
# Set to 'https' when TLS is enabled
# public: https
port:
api:
default: 8080
public: 80
oslo_cache:
auth:
# NOTE(portdirect): this is used to define the value for keystone
# authtoken cache encryption key, if not set it will be populated
# automatically with a random value, but to take advantage of
# this feature all services should be set to use the same key,
# and memcache service.
memcache_secret_key: null
hosts:
default: memcached
host_fqdn_override:
default: null
port:
memcache:
default: 11211
manifests:
configmap_bin: true
configmap_etc: true
deployment_proxy: true
daemonset_storage: true
job_bootstrap: false
job_image_repo_sync: true
job_ks_endpoints: true
job_ks_service: true
job_ks_user: true
job_ring_builder: true
pdb_proxy: true
pdb_storage: true
secret_keystone: true
ingress_proxy: true
service_ingress_proxy: true
service_proxy: true
network_policy: false
pod_test: false
certificates: false
pvc: true
...

View File

@@ -0,0 +1,53 @@
#!/bin/bash
# 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.
set -xe
#NOTE: Define variables
: ${OSH_HELM_REPO:="../openstack-helm"}
: ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"}
: ${OSH_EXTRA_HELM_ARGS_SWIFT:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c swift ${FEATURES})"}
tee /tmp/swift.yaml << EOF
ring:
replicas: 1
devices:
- name: loop100
weight: 100
EOF
#NOTE: Deploy command
helm upgrade --install swift ${OSH_HELM_REPO}/swift \
--namespace=openstack \
--values=/tmp/swift.yaml \
${OSH_EXTRA_HELM_ARGS:=} \
${OSH_EXTRA_HELM_ARGS_SWIFT}
#NOTE: Wait for deploy
helm osh wait-for-pods openstack 1200
openstack service list
openstack endpoint list
# Testing Swift
openstack container list
openstack container create test-container
openstack container list
echo "Hello World" > hello-world.txt
export OPENSTACK_CLIENT_CONTAINER_EXTRA_ARGS="-v $(pwd):/mnt"
openstack object create test-container /mnt/hello-world.txt
openstack object list test-container
openstack object delete test-container /mnt/hello-world.txt
openstack container delete test-container
openstack container list

View File

@@ -0,0 +1,13 @@
---
images:
tags:
bootstrap: quay.io/airshipit/swift:2025.2-ubuntu_noble
test: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_proxy: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_account: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_container: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_object: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_storage: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_storage_init: quay.io/airshipit/swift:2025.2-ubuntu_noble
swift_ring_builder: quay.io/airshipit/swift:2025.2-ubuntu_noble
...

View File

@@ -99,4 +99,15 @@
openstack_release: "2025.2"
container_distro_name: ubuntu
container_distro_version: noble
- job:
name: openstack-helm-swift-2025-2-ubuntu_noble
parent: openstack-helm-swift
nodeset: openstack-helm-3nodes-ubuntu_noble
timeout: 10800
vars:
osh_params:
openstack_release: "2025.2"
container_distro_name: ubuntu
container_distro_version: noble
...

View File

@@ -640,4 +640,29 @@
- ./tools/deployment/component/redis/redis.sh
- ./tools/deployment/component/zaqar/zaqar.sh
- ./tools/deployment/component/zaqar/zaqar_smoke_test.sh
- job:
name: openstack-helm-swift
parent: openstack-helm-deploy
timeout: 10800
files:
- swift/.*
abstract: true
vars:
loopback_format: true
loopback_format_fs_type: ext4
loopback_mount: true
loopback_mount_path: /srv/node/loop100
loopback_image: "/opt/ext_vol/openstack-helm/swift-loop.img"
gate_scripts:
- ./tools/deployment/common/prepare-bashrc.sh
- ./tools/deployment/common/prepare-k8s.sh
- ./tools/deployment/common/prepare-charts.sh
- ./tools/deployment/common/setup-client.sh
- ./tools/deployment/component/nfs-provisioner/nfs-provisioner.sh
- export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh
- ./tools/deployment/db/mariadb.sh
- ./tools/deployment/component/common/memcached.sh
- ./tools/deployment/component/keystone/keystone.sh
- ./tools/deployment/component/swift/swift.sh
...

View File

@@ -54,6 +54,7 @@
- openstack-helm-compute-kit-ovn-2025-2-ubuntu_noble # 1 node + 3 nodes
- openstack-helm-skyline-2025-2-ubuntu_noble # 3 nodes
- openstack-helm-trove-2025-2-ubuntu_noble # 5 nodes rook
- openstack-helm-swift-2025-2-ubuntu_noble # 3 nodes
# Infra jobs
- openstack-helm-logging
- openstack-helm-monitoring