Skip to content

Commit e8a5907

Browse files
paulczarKeerthan Reddy Mala
authored andcommitted
feat: openstack swift support
Adds support for Openstack Swift as object store backend for backups.
1 parent f745e74 commit e8a5907

4 files changed

Lines changed: 169 additions & 23 deletions

File tree

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@ test-unit:
3636
test-functional:
3737
contrib/ci/test.sh ${IMAGE}
3838

39+
test-functional-swift:
40+
contrib/ci/test-swift.sh ${IMAGE}
41+
3942
.PHONY: all docker-build docker-push test

contrib/ci/test-swift.sh

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env bash
2+
3+
set -eof pipefail
4+
5+
# kill containers when this script exits or errors out
6+
trap exit-script INT TERM
7+
8+
puts-step() {
9+
echo "-----> $@"
10+
}
11+
12+
puts-error() {
13+
echo "!!! $@"
14+
}
15+
16+
exit-script() {
17+
kill-containers
18+
kill-swift
19+
}
20+
21+
kill-containers() {
22+
# docker containers
23+
puts-step "destroying postgres container"
24+
docker rm -f deis-postgres-swift
25+
}
26+
27+
kill-swift() {
28+
# swift containers
29+
puts-step "cleaning swift"
30+
swift delete deis-swift-test > /dev/null
31+
}
32+
33+
# make sure we are in this dir
34+
CURRENT_DIR=$(cd $(dirname $0); pwd)
35+
36+
puts-step "creating fake postgres credentials"
37+
38+
# create fake postgres credentials
39+
mkdir -p $CURRENT_DIR/tmp/creds
40+
echo "testuser" > $CURRENT_DIR/tmp/creds/user
41+
echo "icanttellyou" > $CURRENT_DIR/tmp/creds/password
42+
43+
puts-step "fetching openstack credentials"
44+
45+
# check if openstack creds are not already in environment
46+
if [[ -z $OS_USERNAME ]]; then
47+
echo "it appears that you have not loaded your openstack credentials into your environment"
48+
exit 1
49+
fi
50+
51+
# turn creds into something that we can use.
52+
mkdir -p $CURRENT_DIR/tmp/swift
53+
54+
# guess which value to use for tenant:
55+
TENANT=${OS_TENANT_NAME:-$OS_PROJECT_NAME}
56+
TENANT=${TENANT:-$OS_USERNAME}
57+
58+
echo ${OS_USERNAME} > $CURRENT_DIR/tmp/swift/username
59+
echo ${OS_PASSWORD} > $CURRENT_DIR/tmp/swift/password
60+
echo ${TENANT} > $CURRENT_DIR/tmp/swift/tenant
61+
echo ${OS_AUTH_URL} > $CURRENT_DIR/tmp/swift/authurl
62+
echo "deis-swift-test" > $CURRENT_DIR/tmp/swift/database-container
63+
64+
# postgres container command
65+
PG_CMD="docker run -d -e BACKUP_FREQUENCY=3s \
66+
-e DATABASE_STORAGE=swift \
67+
-v $CURRENT_DIR/tmp/creds:/var/run/secrets/deis/database/creds \
68+
-v $CURRENT_DIR/tmp/swift:/var/run/secrets/deis/objectstore/creds \
69+
$1"
70+
71+
# boot postgres
72+
PG_JOB=$(${PG_CMD})
73+
74+
# wait for postgres to boot
75+
puts-step "sleeping for 90s while postgres is booting..."
76+
sleep 90s
77+
78+
# display logs for debugging purposes
79+
puts-step "displaying postgres logs"
80+
docker logs $PG_JOB
81+
82+
# check if postgres is running
83+
puts-step "checking if postgres is running"
84+
docker exec $PG_JOB is_running
85+
86+
# check if swift has some backups ... 3 ?
87+
puts-step "checking if swift has at least 3 backups"
88+
89+
BACKUPS="$(swift list deis-swift-test | grep basebackups_005 | grep json)"
90+
NUM_BACKUPS="$(swift list deis-swift-test | grep basebackups_005 | grep -c json)"
91+
if [[ ! "$NUM_BACKUPS" -gt "3" ]]; then
92+
puts-error "did not find at least 3 base backups, which is the default (found $NUM_BACKUPS)"
93+
puts-error "$BACKUPS"
94+
exit-script
95+
exit 1
96+
fi
97+
98+
puts-step "found $NUM_BACKUPS"
99+
100+
# kill off postgres, then reboot and see if it's running after recovering from backups
101+
puts-step "shutting off postgres, then rebooting to test data recovery"
102+
docker rm -f $PG_JOB
103+
PG_JOB=$(${PG_CMD})
104+
105+
# wait for postgres to boot
106+
puts-step "sleeping for 90s while postgres is recovering from backup..."
107+
sleep 90s
108+
109+
puts-step "displaying postgres logs"
110+
docker logs $PG_JOB
111+
112+
# check if postgres is running
113+
puts-step "checking if postgres is running"
114+
docker exec $PG_JOB is_running
115+
116+
puts-step "tests PASSED!"
117+
exit 0

rootfs/bin/create_bucket

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#!/usr/bin/env python
22

33
import os
4-
import sys
54

65
import boto3
76
import botocore
87
import json
8+
import swiftclient
99
from botocore.utils import fix_s3_host
1010
from botocore.client import Config
1111
from oauth2client.service_account import ServiceAccountCredentials
@@ -30,7 +30,7 @@ if os.getenv('DATABASE_STORAGE') == "s3":
3030
raise
3131

3232
if not exists:
33-
conn.create_bucket(Bucket=bucket_name)
33+
conn.create_bucket(Bucket=bucket_name)
3434

3535
elif os.getenv('DATABASE_STORAGE') == "gcs":
3636
scopes = ['https://www.googleapis.com/auth/devstorage.full_control']
@@ -46,28 +46,39 @@ elif os.getenv('DATABASE_STORAGE') == "gcs":
4646
except:
4747
raise
4848
if not exists:
49-
client.create_bucket(bucket_name)
49+
client.create_bucket(bucket_name)
5050

5151
elif os.getenv('DATABASE_STORAGE') == "azure":
52-
block_blob_service = BlockBlobService(account_name=os.getenv('WABS_ACCOUNT_NAME'), account_key=os.getenv('WABS_ACCESS_KEY'))
53-
#It doesn't throw an exception if the container exists by default(https://github.com/Azure/azure-storage-python/blob/master/azure/storage/blob/baseblobservice.py#L504).
54-
block_blob_service.create_container(bucket_name)
52+
block_blob_service = BlockBlobService(account_name=os.getenv('WABS_ACCOUNT_NAME'), account_key=os.getenv('WABS_ACCESS_KEY'))
53+
#It doesn't throw an exception if the container exists by default(https://github.com/Azure/azure-storage-python/blob/master/azure/storage/blob/baseblobservice.py#L504).
54+
block_blob_service.create_container(bucket_name)
5555

56-
else :
57-
conn = boto3.resource('s3', endpoint_url=os.getenv('S3_URL'), config=Config(signature_version='s3v4'))
58-
# stop boto3 from automatically changing the endpoint
59-
conn.meta.client.meta.events.unregister('before-sign.s3', fix_s3_host)
60-
exists = True
61-
try:
62-
conn.meta.client.head_bucket(Bucket=bucket_name)
63-
except botocore.exceptions.ClientError as e:
64-
# If a client error is thrown, then check that it was a 404 error.
65-
# If it was a 404 error, then the bucket does not exist.
66-
error_code = int(e.response['Error']['Code'])
67-
if error_code == 404:
68-
exists = False
69-
else:
70-
raise
56+
elif os.getenv('DATABASE_STORAGE') == "swift":
57+
conn = swiftclient.Connection(
58+
user=os.getenv('SWIFT_USER'),
59+
key=os.getenv('SWIFT_PASSWORD'),
60+
authurl=os.getenv('SWIFT_AUTHURL'),
61+
auth_version=os.getenv('SWIFT_AUTH_VERSION'),
62+
tenant_name=os.getenv('SWIFT_TENANT')
63+
)
64+
# swift also does not throw exception if container already exists.
65+
conn.put_container(os.getenv('BUCKET_NAME'))
7166

72-
if not exists:
73-
conn.create_bucket(Bucket=bucket_name)
67+
else:
68+
conn = boto3.resource('s3', endpoint_url=os.getenv('S3_URL'), config=Config(signature_version='s3v4'))
69+
# stop boto3 from automatically changing the endpoint
70+
conn.meta.client.meta.events.unregister('before-sign.s3', fix_s3_host)
71+
exists = True
72+
try:
73+
conn.meta.client.head_bucket(Bucket=bucket_name)
74+
except botocore.exceptions.ClientError as e:
75+
# If a client error is thrown, then check that it was a 404 error.
76+
# If it was a 404 error, then the bucket does not exist.
77+
error_code = int(e.response['Error']['Code'])
78+
if error_code == 404:
79+
exists = False
80+
else:
81+
raise
82+
83+
if not exists:
84+
conn.create_bucket(Bucket=bucket_name)

rootfs/docker-entrypoint-initdb.d/001_setup_envdir.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,19 @@ elif [ "$DATABASE_STORAGE" == "azure" ]; then
4040
echo $WABS_ACCESS_KEY > WABS_ACCESS_KEY
4141
echo "wabs://$BUCKET_NAME" > WALE_WABS_PREFIX
4242
echo $BUCKET_NAME > BUCKET_NAME
43+
elif [ "$DATABASE_STORAGE" == "swift" ]; then
44+
SWIFT_USER=$(cat /var/run/secrets/deis/objectstore/creds/username)
45+
SWIFT_PASSWORD=$(cat /var/run/secrets/deis/objectstore/creds/password)
46+
SWIFT_TENANT=$(cat /var/run/secrets/deis/objectstore/creds/tenant)
47+
SWIFT_AUTHURL=$(cat /var/run/secrets/deis/objectstore/creds/authurl)
48+
SWIFT_AUTH_VERSION=$(cat /var/run/secrets/deis/objectstore/creds/authversion)
49+
BUCKET_NAME=$(cat /var/run/secrets/deis/objectstore/creds/database-container)
50+
# set defaults for variables that we can guess at
51+
echo $SWIFT_USER > SWIFT_USER
52+
echo $SWIFT_PASSWORD > SWIFT_PASSWORD
53+
echo $SWIFT_TENANT > SWIFT_TENANT
54+
echo $SWIFT_AUTHURL > SWIFT_AUTHURL
55+
echo $SWIFT_AUTH_VERSION > SWIFT_AUTH_VERSION
56+
echo "swift://$BUCKET_NAME" > WALE_SWIFT_PREFIX
57+
echo $BUCKET_NAME > BUCKET_NAME
4358
fi

0 commit comments

Comments
 (0)