Skip to content

Commit 5c994a3

Browse files
committed
delete cluster suppurt delete s3 backup
1 parent 65b5e62 commit 5c994a3

File tree

4 files changed

+116
-30
lines changed

4 files changed

+116
-30
lines changed

image/postgresql/pgtools

+30-12
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ ROLE_MASTER="master"
7575
ROLE_SLAVE="slave"
7676
ROLE_UNKNOWN="unknown"
7777
BARMAN_S3_PARAM='echo --cloud-provider aws-s3 -P default --endpoint-url $S3_ENDPOINT s3://$S3_BUCKET/$S3_PATH $BARMAN_BACKUPNAME'
78+
BARMAN_BASE_DIR="base"
79+
BARMAN_WALS_DIR="wals"
80+
BARMAN_RENTION_DELETE_ALL="delete_all"
7881

7982
BACKUP_RESTORE_CONF="postgresql_backup_restore.conf"
8083
###########
@@ -376,19 +379,24 @@ function s3_backup() {
376379
fi
377380
}
378381

382+
function get_aws_param() {
383+
if [ "${S3_PATH: 0: 1}" == "/" ]; then
384+
S3_PATH=${S3_PATH: 1}
385+
fi
386+
if [ "$S3_PATH" ]; then
387+
param="s3://$S3_BUCKET/$S3_PATH/$BARMAN_BACKUPNAME/"
388+
else
389+
param="s3://$S3_BUCKET/$BARMAN_BACKUPNAME/"
390+
fi
391+
echo $param
392+
}
393+
379394
function get_backup_info_or_backup_size() {
380395
check_and_generate_s3_profile
381396
if [ $BACKUP_ID ]; then
382397
check_backup_exists
383-
if [ "${S3_PATH: 0: 1}" == "/" ]; then
384-
S3_PATH=${S3_PATH: 1}
385-
fi
386-
if [ "$S3_PATH" ]; then
387-
param="s3://$S3_BUCKET/$S3_PATH/$BARMAN_BACKUPNAME/base/$BACKUP_ID/"
388-
else
389-
param="s3://$S3_BUCKET/$BARMAN_BACKUPNAME/base/$BACKUP_ID/"
390-
fi
391-
aws s3 --profile default --endpoint-url $S3_ENDPOINT ls $param --human-readable --summarize | grep 'Total Size:' | awk -F ':' '{print $2}'
398+
param=$(get_aws_param)
399+
aws s3 --profile default --endpoint-url $S3_ENDPOINT ls "${param}${BARMAN_BASE_DIR}/${BACKUP_ID}/" --human-readable --summarize | grep 'Total Size:' | awk -F ':' '{print $2}'
392400
else
393401
barman-cloud-backup-list $(eval $BARMAN_S3_PARAM) --format json
394402
fi
@@ -407,9 +415,19 @@ function delete_backup() {
407415
check_and_generate_s3_profile
408416
if [ ! "$retention" -o "$retention" == "none" ]; then
409417
check_error 1 "delete_backup but retention env is not set or retention is none."
418+
elif [ "$retention" == "$BARMAN_RENTION_DELETE_ALL" ]; then
419+
param=$(get_aws_param)
420+
output1=$(aws s3 --profile default --endpoint-url $S3_ENDPOINT ls $param | wc -l)
421+
output2=$(aws s3 --profile default --endpoint-url $S3_ENDPOINT ls $param | grep -w "${BARMAN_BASE_DIR}\|${BARMAN_WALS_DIR}" | wc -l)
422+
# check dir is valid
423+
if [ "$output1" == "2" -a "$output2" == "2" ]; then
424+
aws s3 --profile default --endpoint-url $S3_ENDPOINT rm $param --recursive
425+
check_error $? "delete_backup failed, please check error log"
426+
fi
427+
else
428+
delete_backup_by_policy
429+
check_error $? "delete_backup failed, please check error log"
410430
fi
411-
delete_backup_by_policy
412-
check_error $? "delete_backup failed, please check error log"
413431
}
414432

415433
function check_backup_exists() {
@@ -571,7 +589,7 @@ if [ "${do_query}" = 1 ]; then
571589
if [ $? != 0 ]; then
572590
check_error 1 "failed."
573591
fi
574-
592+
575593
max_querys=`expr ${#querys[@]} - 1`
576594
for i in `seq 0 "$max_querys"`
577595
do

platforms/kubernetes/postgres-operator/deploy/postgres-operator.yaml.template

+6
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ spec:
118118
enum:
119119
- true
120120
- false
121+
deletes3:
122+
type: boolean
123+
enum:
124+
- true
125+
- false
126+
default: false
121127
updatetoleration:
122128
type: boolean
123129
enum:

platforms/kubernetes/postgres-operator/postgres/constants.py

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
STREAMING_ASYNC = "async"
3333
STREAMING_SYNC = "sync"
3434
DELETE_PVC = "deletepvc"
35+
SPEC_DELETE_S3 = "deletes3"
3536
UPDATE_TOLERATION = "updatetoleration"
3637
POSTGRESQL_PVC_NAME = "data"
3738
SUCCESS = "exec_success"
@@ -66,6 +67,7 @@
6667
SPEC_BACKUPTOS3_POLICY_ENCRYPTION_DEFAULT_VALUE = "none"
6768
SPEC_BACKUPTOS3_POLICY_RETENTION = "retention"
6869
SPEC_BACKUPTOS3_POLICY_RETENTION_DEFAULT_VALUE = "none"
70+
SPEC_BACKUPTOS3_POLICY_RETENTION_DELETE_ALL_VALUE = "delete_all"
6971
RESTORE = "restore"
7072
RESTORE_FROMSSH = "fromssh"
7173
RESTORE_FROMSSH_PATH = "path"

platforms/kubernetes/postgres-operator/postgres/handle.py

+78-18
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
SPEC_BACKUPTOS3_POLICY_ENCRYPTION_DEFAULT_VALUE,
170170
SPEC_BACKUPTOS3_POLICY_RETENTION,
171171
SPEC_BACKUPTOS3_POLICY_RETENTION_DEFAULT_VALUE,
172+
SPEC_BACKUPTOS3_POLICY_RETENTION_DELETE_ALL_VALUE,
172173
RESTORE_FROMS3,
173174
RESTORE_FROMS3_NAME,
174175
RESTORE_FROMS3_RECOVERY,
@@ -182,6 +183,7 @@
182183
PG_LOG_FILENAME,
183184
SPEC_REBUILD,
184185
SPCE_REBUILD_NODENAMES,
186+
SPEC_DELETE_S3,
185187
)
186188

187189
PGLOG_DIR = "log"
@@ -319,6 +321,8 @@
319321
BACKUP_MODE_NONE = "none"
320322
BACKUP_MODE_S3_MANUAL = "manual"
321323
BACKUP_MODE_S3_CRON = "cron"
324+
GET_ENV_MODE_BACKUP = "backup"
325+
GET_ENV_MODE_RESTORE = "restore"
322326

323327
SPECIAL_CHARACTERS = "/##/"
324328

@@ -1715,6 +1719,41 @@ def get_policy_env(policy: TypedDict) -> List:
17151719
return res
17161720

17171721

1722+
def get_need_s3_env(
1723+
meta: kopf.Meta,
1724+
spec: kopf.Spec,
1725+
patch: kopf.Patch,
1726+
status: kopf.Status,
1727+
logger: logging.Logger,
1728+
mode: str,
1729+
need_envs: List = None,
1730+
) -> List:
1731+
res = list()
1732+
1733+
if need_envs is None:
1734+
need_envs = ["name", SPEC_S3, SPEC_BACKUPTOS3_POLICY]
1735+
1736+
if SPEC_S3 in need_envs:
1737+
# add s3 env by pgtools
1738+
s3 = spec[SPEC_S3].copy()
1739+
res.append(get_s3_env(s3))
1740+
1741+
if SPEC_BACKUPTOS3_POLICY in need_envs:
1742+
backup_policy = spec[SPEC_BACKUPCLUSTER][SPEC_BACKUPTOS3].get(
1743+
SPEC_BACKUPTOS3_POLICY, {})
1744+
res.append(get_policy_env(backup_policy))
1745+
1746+
if "name" in need_envs:
1747+
if mode == GET_ENV_MODE_BACKUP:
1748+
name = spec[SPEC_BACKUPCLUSTER][SPEC_BACKUPTOS3].get(
1749+
SPEC_BACKUPTOS3_NAME, None)
1750+
elif mode == GET_ENV_MODE_RESTORE:
1751+
name = spec[RESTORE][RESTORE_FROMS3].get(RESTORE_FROMS3_NAME, None)
1752+
res.append(get_backup_name_env(meta, name))
1753+
1754+
return res
1755+
1756+
17181757
def restore_postgresql_froms3(
17191758
meta: kopf.Meta,
17201759
spec: kopf.Spec,
@@ -1732,10 +1771,7 @@ def restore_postgresql_froms3(
17321771
name = spec[RESTORE][RESTORE_FROMS3].get(RESTORE_FROMS3_NAME, None)
17331772

17341773
# add s3 env by pgtools -e
1735-
s3 = spec[SPEC_S3].copy()
1736-
s3_list = get_s3_env(s3)
1737-
name_list = get_backup_name_env(meta, name)
1738-
s3_info = [*s3_list, *name_list]
1774+
s3_info = get_need_s3_env(meta, spec, patch, status, logger, GET_ENV_MODE_RESTORE, [SPEC_S3, "name"])
17391775

17401776
tmpconns: InstanceConnections = InstanceConnections()
17411777
tmpconns.add(conn)
@@ -2003,18 +2039,7 @@ def backup_postgresql_to_s3(
20032039
waiting_postgresql_ready(conns, logger)
20042040

20052041
# add s3 env by pgtools
2006-
s3 = spec[SPEC_S3].copy()
2007-
s3_list = get_s3_env(s3)
2008-
2009-
backup_policy = spec[SPEC_BACKUPCLUSTER][SPEC_BACKUPTOS3].get(
2010-
SPEC_BACKUPTOS3_POLICY, {})
2011-
policy_list = get_policy_env(backup_policy)
2012-
2013-
name = spec[SPEC_BACKUPCLUSTER][SPEC_BACKUPTOS3].get(
2014-
SPEC_BACKUPTOS3_NAME, None)
2015-
name_list = get_backup_name_env(meta, name)
2016-
2017-
s3_info = [*s3_list, *policy_list, *name_list]
2042+
s3_info = get_need_s3_env(meta, spec, patch, status, logger, GET_ENV_MODE_BACKUP, [])
20182043

20192044
cmd = ["pgtools", "-b"] + s3_info
20202045
logging.warning(
@@ -3423,6 +3448,40 @@ def delete_storage(
34233448
"rm -rf " + machine_data_path)
34243449

34253450

3451+
def delete_s3(
3452+
meta: kopf.Meta,
3453+
spec: kopf.Spec,
3454+
patch: kopf.Patch,
3455+
status: kopf.Status,
3456+
logger: logging.Logger,
3457+
) -> None:
3458+
if get_backup_mode(meta, spec, patch, status,
3459+
logger) == BACKUP_MODE_S3_MANUAL or get_backup_mode(
3460+
meta, spec, patch, status,
3461+
logger) == BACKUP_MODE_S3_CRON:
3462+
s3_info = get_need_s3_env(meta, spec, patch, status, logger, GET_ENV_MODE_BACKUP, [])
3463+
3464+
# override rentention variable
3465+
env = SPEC_BACKUPTOS3_POLICY_RETENTION + '="' + \
3466+
SPEC_BACKUPTOS3_POLICY_RETENTION_DELETE_ALL_VALUE + '"'
3467+
s3_info.append('-e')
3468+
s3_info.append(env)
3469+
3470+
readwrite_conns = connections(spec, meta, patch,
3471+
get_field(POSTGRESQL, READWRITEINSTANCE),
3472+
False, None, logger, None, status, False)
3473+
waiting_instance_ready(readwrite_conns, logger, timeout=1 * MINUTES)
3474+
for conn in readwrite_conns.get_conns():
3475+
# delete all backup
3476+
cmd = ["pgtools", "-B"] + s3_info
3477+
output = exec_command(conn,
3478+
cmd,
3479+
logger,
3480+
interrupt=True,
3481+
user="postgres")
3482+
logger.warning(f"delete all backup execute on {get_connhost(conn)}, and output = {output}")
3483+
3484+
34263485
def delete_storages(
34273486
meta: kopf.Meta,
34283487
spec: kopf.Spec,
@@ -3459,6 +3518,8 @@ def delete_postgresql_cluster(
34593518
status: kopf.Status,
34603519
logger: logging.Logger,
34613520
) -> None:
3521+
if spec[SPEC_DELETE_S3]:
3522+
delete_s3(meta, spec, patch, status, logger)
34623523
if spec[DELETE_PVC]:
34633524
delete_storages(meta, spec, patch, status, logger)
34643525

@@ -3777,8 +3838,7 @@ def correct_s3_profile(
37773838
logger) == BACKUP_MODE_S3_MANUAL or get_backup_mode(
37783839
meta, spec, patch, status,
37793840
logger) == BACKUP_MODE_S3_CRON:
3780-
s3 = spec[SPEC_S3].copy()
3781-
s3_info = get_s3_env(s3)
3841+
s3_info = get_need_s3_env(meta, spec, patch, status, logger, GET_ENV_MODE_BACKUP, [SPEC_S3])
37823842
readwrite_conns = connections(spec, meta, patch,
37833843
get_field(POSTGRESQL, READWRITEINSTANCE),
37843844
False, None, logger, None, status, False)

0 commit comments

Comments
 (0)