VMware Networking Community
MtheG92
Enthusiast
Enthusiast

NSX-T backup successful but missing ccp-backups folder

Hi

 

We successfully configured our two NSX-T Manager (version 3.1.3.6.0) environments to send backups to our SFTP backup target. Each NSX-T Manager Cluster has its own directory "/data/backups/{nsx-manager-cluster-name}/".

 

We tried to implement the "nsx_backup_cleaner.py" on the SFTP target but got the following error message: Cleanup script works only in folders, that contains subfolders "cluster-node-backups", "ccp-backups" and "inventory-summary"

 

I verified the backups directories and for both NSX-T Manager environments only the "ccp-backups" directory is missing.

 

Both NSX-T Manager are successfully configured, and every scheduled backup was successfully processed. We do not see any issues on the SFTP target. 

 

Did anyone else face this problem or has an idea of what's wrong here? 

 

Thanks in advance.

Tags (3)
Reply
0 Kudos
5 Replies
MtheG92
Enthusiast
Enthusiast

Hi

 

I have received feedback from the VMware support, and they stated that in newer NSX-T (3.1.x and 3.2.x) versions there is no more ccp-backups folder created. In 3.2.x they removed the folder from the cleanup script.

 

Kind regards

Reply
0 Kudos
itsamorey
Contributor
Contributor

Same experience for me.

But it appears as though they have NOT removed folder from the cleanup script.

backup_dirs = os.listdir(BACKUP_ROOT)
if (all(elem in ["cluster-node-backups", "inventory-summary", "ccp-backups"] for elem in backup_dirs)):
for elem in backup_dirs:
if (elem in ["cluster-node-backups"]):
delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'cluster-node-backups'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
if (elem in ["inventory-summary"]):
delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'inventory-summary'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
if (elem in ["ccp-backups"]):
delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'ccp-backups'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)

Reply
0 Kudos
MtheG92
Enthusiast
Enthusiast

Interesting… I got the script directly from the NSX Support and it seems they removed the "if (elem in ["ccp-backups"]): […]" line in the cleanup script. I did not test it myself with an actual cleanup script from an original NSX 3.2.x Manager Node.   

Here the script I got from the NSX Support team:

 

#!/usr/bin/env python
# ***************************************************************************
# Copyright 2020-2021 VMware, Inc.  All rights reserved. VMware Confidential.
# ***************************************************************************
# The purpose of this script is to remove old NSX backup files. Typically, this script
# will be placed on the SFTP server where the NSX Manager is uploading backup files,
# and included into a scheduler, for example cron.  Before running this script, you
# should update the BACKUP_ROOT variable.  This script works on Linux and Windows with
# both Python 2 and Python 3.
#
# On Linux SFTP server:
# You can add this script in the crontab to automatically run this script once daily
# Edit the anacron at /etc/cron.d or use crontab -e and add following line to execute the script at 10am everyday
# 00 10 * * * /sbin/nsx_backup_cleaner.py
#
# On Windows SFTP server:
# schtasks /Create /SC DAILY /TN PythonTask /TR "PATH_TO_PYTHON_EXE PATH_TO_PYTHON_SCRIPT"
# or you can add the same in TaskScheduler



from stat import S_ISREG, ST_ATIME, ST_CTIME, ST_MODE, S_ISDIR, S_IWUSR
import os, sys, time, datetime, shutil, getopt

def delete_files(delete_path_list, count):
    deleted_files = []

    for file in delete_path_list:
        for root, dirs, files in os.walk(file):
            for fname in files:
                full_path = os.path.join(root, fname)
                os.chmod(full_path, S_IWUSR)
        if count > 0:
            deleted_files.append(file)
            if os.path.isdir(file):
                shutil.rmtree(file)
            else:
                os.remove(file)
            count = count - 1
    return deleted_files


def delete_old_backup_enteries(folder, keep_days, min_count):
    keep_files = []
    for elem in os.listdir(folder):
        paths_sorted = []
        entries1 = (os.path.join(folder, elem, fn) for fn in os.listdir(os.path.join(folder, elem)))
        entries2 = ((os.stat(path), path) for path in entries1)
        entries3 = ((stat[ST_CTIME], path) for stat, path in entries2)
        for cdate, path in sorted(entries3):
            paths_sorted.append(path)

        if (len(paths_sorted) <= min_count):
            for file in paths_sorted:
                keep_files.append(file)
            continue

        delete_path_list = []
        for path in paths_sorted:
            file_create_time = os.path.getmtime(path)
            time_now = time.time()
            if ((time_now - file_create_time) > (keep_days * 24 * 60 * 60)):
                delete_path_list.append(path)

        deleted_files = delete_files(delete_path_list, min(len(delete_path_list), len(paths_sorted) - min_count))
        for file in deleted_files:
            paths_sorted.remove(file)

        for file in paths_sorted:
            keep_files.append(file)

    print(("Keeping the following backup files for folder %s" % folder))
    for file in keep_files:
        print(file)

def usage():
    print("""\
    Usage: nsx_backup_cleaner.py -d backup_dir [-k 1] [-l 5] [-h]
           Or
           nsx_backup_cleaner.py --dir backup_dir [--retention-period 1] [--min-count 5] [--help]

           Required
               -d/--dir: Backup root directory
               -k/--retention-period: Number of days need to retain a backup file
           Optional
               -l/--min-count: Minimum number of backup files to be kept, default value is 100
               -h/--help: Display help message
           """)
def main():
    BACKUP_ROOT = None

    BACKUPS_KEEP_DAYS = None
    # Minimum allowed: 100
    BACKUPS_MINCOUNT = 100

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hd:k:l:", ["dir=", "retention-period=", "min-count=", "help"])
    except getopt.GetoptError as err:
    # print help information and exit:
        print ((str(err))) # will print something like "option -a not recognized"
        usage()
        sys.exit()

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt in ("-d", "--dir"):
            BACKUP_ROOT = arg
        elif opt in("-k", "--retention-period"):
            BACKUPS_KEEP_DAYS = int(arg)
        elif opt in ("-l", "--min-count"):
            BACKUPS_MINCOUNT = int(arg)
        else:
            usage()
            sys.exit()

    if (BACKUP_ROOT == None):
        print("Missing Backup Root")
        usage()
        sys.exit()

    if (BACKUPS_KEEP_DAYS == None):
        print("Missing Backup Retention Period in number of days")
        usage()
        sys.exit()

    if (not os.path.isdir(BACKUP_ROOT)):
        print("Wrong backup root directory")
        usage()
        sys.exit()

    backup_dirs = os.listdir(BACKUP_ROOT)
    if (all(elem in ["cluster-node-backups", "inventory-summary"] for elem in backup_dirs)):
        for elem in backup_dirs:
            if (elem in ["cluster-node-backups"]):
                delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'cluster-node-backups'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
            if (elem in ["inventory-summary"]):
                delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'inventory-summary'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
    else:
        print ("Cleanup script works only in folders, that contains subfolders \"cluster-node-backups\" and \"inventory-summary\"")


if __name__ == "__main__":
    main()

 

Reply
0 Kudos
BeardedMallard
Contributor
Contributor

I had similar problems but it seems that the script is looking for a backup folder with only those folders in it. If you have other things it may fail. Remove them and test again.

For VCF managed systems the SDDC manager will update your NSX-T nodes with the new backup location but also put the SDDC manager backup folder in the same directory. I haven't tested but I think the retention set by the SDDC manager only applies to the SDDC manager backup and not the NSX-T ones.

This is tricky because the nsx_backup_cleaner.py doesn't like the extra folder in the backup location we're telling it to clean. I added the name of the SDDC manager backup folder into this line of the nsx_backup_cleaner.py file so it wouldn't fail.

if (all(elem in ["cluster-node-backups", "inventory-summary"] for elem in backup_dirs)):

This is sub-optimal because I expect the SDDC manager to deal with this but perhaps they didn't consider it.

rk602
Contributor
Contributor

Thanks BeardedMallard, your tip was enough to get it working for me, I had to comment out some lines and remove ccp-backups from the first line, as shown below

if (all(elem in ["cluster-node-backups", "inventory-summary", "lcm", "scripts"] for elem in backup_dirs)):
for elem in backup_dirs:
if (elem in ["cluster-node-backups"]):
delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'cluster-node-backups'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
if (elem in ["inventory-summary"]):
delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'inventory-summary'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
#if (elem in ["ccp-backups"]):
# delete_old_backup_enteries(os.path.join(BACKUP_ROOT, 'ccp-backups'), BACKUPS_KEEP_DAYS, BACKUPS_MINCOUNT)
else:
print ("Cleanup script works only in folders, that contains subfolders \"cluster-node-backups\", \"ccp-backups\" and \"inventory-summary\"")

Reply
0 Kudos