GIF89a=( �' 7IAXKgNgYvYx\%wh&h}t�h%�s%x�}9�R��&�0%� (�.��5�SD��&�a)�x5��;ͣ*ȡ&ղ)ׯ7׵<ѻ4�3�H֧KͯT��Y�aq��q��F� !� ' !� NETSCAPE2.0 , =( ��pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g���E�������R���E����B�� ��ȸ��D���"�Ů� �H��L��D٫D�B�����D���T���H �G��A R�ڐ |�� ٭&��E8�S�kG�A�px�a��� R2XB��E8I���6X�:vT)�~��q�賥��"F~%x� � 4#Z�0O|-4Bs�X:= Q� Sal��yXJ`GȦ|s h��K3l7�B|�$'7Jީܪ0!��D�n=�P� ����0`�R�lj����v>���5 �.69�ϸd�����nlv�9��f{���Pbx �l5}�p� ��� �3a���I�O����!ܾ���i��9��#��)p�a ޽ �{�)vm��%D~ 6f��s}Œ�D�W E�`!� �&L8x� �ܝ{)x`X/>�}m��R�*|`D�=�_ ^�5 !_&'a�O�7�c��`DCx`�¥�9�Y�F���`?��"� �n@`�} lď��@4>�d S �v�xN��"@~d��=�g�s~G��� ���ud &p8Q�)ƫlXD����A~H�ySun�j���k*D�LH�] ��C"J��Xb~ʪwSt}6K,��q�S:9ت:���l�@�`�� �.۬�t9�S�[:��=`9N����{¿�A !R�:���6��x�0�_ �;������^���#����!����U���;0L1�����p% A��U̬ݵ��%�S��!���~`�G���� ���=4�np�3���������u�u�ٮ|%2�I��r�#0��J``8�@S@5� ���^`8E�]�.�S���7 � �0�j S�D� z���i�S�����!���l��w9*�D�I�nEX��� &A�Go�Qf��F��;���}�J����F5��Q|���X��T��y���]� o ��C=��:���PB@ D׽S�(>�C�x}`��xJЬ�۠��p+eE0`�}`A �/NE�� �9@��� H�7�!%B0`�l*��!8 2�%� �:�1�0E��ux%nP1�!�C)�P81l�ɸF#Ƭ{����B0>�� �b�`��O3��()yRpb��E.ZD8�H@% �Rx+%���c� ���f��b�d�`F�"8�XH"��-�|1�6iI, 2�$+](A*j� QT�o0.�U�`�R�}`�SN����yae�����b��o~ S)�y�@��3 �tT�0�&�+~L�f"�-|�~��>!�v��~�\Q1)}@�}h#aP72�"�$ !� " , =( &7IAXG]KgNgYvYxR"k\%w]'}h}t�h%�g+�s%r.m3ax3�x�}9��&��+�!7�0%� (�.�SD��&��;�"&ײ)׻4��6�K� �@pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g �� E �� �������E �´��C���ǶR��D��"Ʒ�ʱH��M��GڬD�B����D��T����G���C�C� l&�~:'�tU�6ɹ#��)�'�.6�&��Ȼ K(8p0N�?!�2"��NIJX>R��OM '��2�*x�>#n� �@<[:�I�f ��T���Cdb��[�}E�5MBo��@�`@��tW-3 �x�B���jI�&E�9[T&$��ﯧ&"s��ȳ����dc�UUρ#���ldj?����`\}���u|3'�R]�6 �S#�!�FKL�*N E���`$�:e�YD�q�.�촁�s \-�jA 9�����-��M[�x(�s��x�|���p��}k�T�DpE@W� ��]k`1� ���Yb ��0l��*n0��"~zBd�~u�7�0Bl��0-�x~|U�U0 �h�*HS�|��e"#"?vp�i`e6^�+q��`m8 #V�� ��VS|`��"m"сSn|@:U���~`pb�G�ED����2F�I�? >�x� R� ��%~jx��<�a�9ij�2�D��&: Z`�]w���:�6��B�7eFJ|�ҧ�,���FǮcS�ʶ+B�,�ܺN���>PAD�HD��~���n��}�#�� Q��S���2�X�{�k�lQ�2�����w�|2� h9��G�,m���3��6-��E�L��I�³*K���q�`DwV�QXS��peS��� qܧTS����R�u �<�a�*At�lmE� � ��N[P1�ۦ��$��@`��Dpy�yXvCAy�B`}D� 0QwG#� �a[^�� $���Ǧ{L�"[��K�g�;�S~��GX.�goT.��ư��x���?1z��x~:�g�|�L� ��S`��0S]P�^p F<""�?!,�!N4&P� ����:T�@h�9%t��:�-~�I<`�9p I&.)^ 40D#p@�j4�ج:�01��rܼF2oW�#Z ;$Q q  �K��Nl#29 !F@�Bh�ᏬL!XF�LHKh�.�hE&J�G��<"WN!�����Y@� >R~19J"�2,/ &.GXB%�R�9B6�W]���W�I�$��9�RE8Y� ��"�A5�Q.axB�&ة�J�! �t)K%tS-�JF b�NMxL��)�R��"���6O!TH�H� 0 !� ) , =( &AXKgNgYvYxR"k\%wh&h}h%�g+�s%r.x3�x�}9��&��+�R,�!7�0%� (�.��5��&�a)��;�"&ף*Ȳ)ׯ7׻4�3��6�H֧KͻH�T��Y��q��h� ��pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g �� E$����� � ����$E$��"��D� � ������R��C��� E ��H�M��G�D� �B��ϾD��a��`1r��Ӑ�� �o~�zU!L�C'�yW�UGt����ll�0���uG�)A�s[��x� �xO%��X2�  P�n:R/��aHae+�Dm?# ǣ6�8�J�x�Di�M���j���5oQ7�- <! *�l��R2r/a!l)d� A"�E���� &� ;��c �%����b��pe~C"B���H�eF2��`8qb�t_`ur`e� w�u3��Pv�h""�`�Íx�LĹ��3� �~ֺ�:���MDfJ� �۵�W�%�S�X �؁)�@��:E��w�u�Sxb8y\m�zS��Zb�E�L��w!y(>�"w�=�|��s�d �C�W)H�cC$�L �7r.�\{)@�`@ �X�$PD `aaG:���O�72E�amn]�"Rc�x�R� &dR8`g��i�xLR!�P &d����T���i�|�_ � Qi�#�`g:��:noM� :V �)p����W&a=�e�k� j���1߲s�x�W�jal|0��B0�, \j۴:6���C ��W��|��9���zĸV {�;��n��V�m�I��.��PN� ����C��+��By�ѾHŸ:��� 7�Y�FTk�SaoaY$D�S���29R�kt� ��f� ��:��Sp�3�I��DZ� �9���g��u�*3)O��[_hv ,���Et x�BH� �[��64M@�S�M7d�l�ܶ5-��U܍��z�R3Ԭ3~ ��P��5�g: ���kN�&0�j4���#{��3S�2�K�'ợl���2K{� {۶?~m𸧠�I�nE�='����^���_�=��~�#O���'���o..�Y�n��CSO��a��K��o,���b�����{�C�� "�{�K ��w��Ozdը�:$ ���v�] A#� ���a�z)Rx׿ƥ�d``�w-�y�f�K!����|��P��=�`�(f��'Pa ��BJa%��f�%`�}F����6>��`G"�}�=�!o`�^FP�ةQ�C���`(�}\�ݮ ��$<��n@dĠE#��U�I�!� #l��9`k���'Rr��Z�NB�MF �[�+9���-�wj���8�r� ,V�h"�|�S=�G_��"E� 0i*%̲��da0mVk�):;&6p>�jK ��# �D�:�c?:R Ӭf��I-�"�<�="��7�3S��c2RW ,�8(T"P0F¡Jh�" ; 403WebShell
403Webshell
Server IP : 173.249.157.85  /  Your IP : 18.221.54.244
Web Server : Apache
System : Linux server.frogzhost.com 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64
User : econtech ( 1005)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /lib/Acronis/PyShell/site-tools/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /lib/Acronis/PyShell/site-tools/cleanup_backups.py
# Script allows to cleanup target machine's DML DB from foreign archives and backups
#
# Requirements:
#    - Installed Acronis Cyber Protection agent
#    - Running of the script requires admin rights
#
# Notes:
#    By default script 
#      - Will be running in report mode, to display statistics related to archives and backups that are bounded to a machine
#      - Uses agent's DML database, so script will try to stop MMS service first, apply required actions, then start MMS
#        override path with --db-path option (or -d), in that case MMS service will not be touched
#      - Uses machine ID's from registry, override it with --machine-id option (or -m)
#      - Cleanup mode is turned off, override it with --cleanup option (or -c)

# To run script in report mode for current machine
# "C:\Program Files\Acronis\PyShell\python.exe" cleanup_backups.py

# To run script in cleanup mode for current machine
# "C:\Program Files\Acronis\PyShell\python.exe" cleanup_backups.py -c

# To run script in cleanup mode for current machine and for specified location only
# "C:\Program Files\Acronis\PyShell\python.exe" cleanup_backups.py -c -l 8F44EB8E-E15E-4B3E-BBC4-40924F7EE303

# To run script in report mode for a specific machine
# "C:\Program Files\Acronis\PyShell\python.exe" cleanup_backups.py -m D6E857EF-6781-4AB2-97A5-AD20A15D3E27

# To run script in cleanup mode for a specific machine (all foreign archives and backups will be removed except specified machine)
# "C:\Program Files\Acronis\PyShell\python.exe" cleanup_backups.py -c -m D6E857EF-6781-4AB2-97A5-AD20A15D3E27

# To run script in cleanup mode for custom DB path
# "C:\Program Files\Acronis\PyShell\python.exe" cleanup_backups.py -c -d D:\TTASK-50248\var\lib\Acronis\BackupAndRecovery\MMSData\DML\F4CEEE47-042C-4828-95A0-DE44EC267A28.db3

# If everything is good then script should be finished with output "Successfully finished."

import acrort
import argparse
import os
import platform
import re
import subprocess
import sys
import time


OS_WINDOWS = 'Windows'
OS_LINUX = 'Linux'
OS_MAC = 'Darwin'

CHUNK_SIZE = 250

data = {
    OS_WINDOWS: {
      'product_path': lambda x: get_windows_product_installation_path(),
      'start_mms_args': ['sc', 'start', 'mms'],
      'stop_mms_args': ['sc', 'stop', 'mms'],
    },
    OS_LINUX: {
      'product_path': '/usr/lib/' + acrort.common.BRAND_NAME, 
      'start_mms_args': ['service', 'acronis_mms', 'start'],
      'stop_mms_args': ['service', 'acronis_mms', 'stop'],
    },
    OS_MAC: {
      'product_path': '/Library/Application Support/BackupClient/' + acrort.common.BRAND_NAME,
      'start_mms_args': ['launchctl', 'start', 'acronis_mms'],
      'stop_mms_args': ['launchctl', 'stop', 'acronis_mms'],
    }
}

def is_guid(key):
    RE_UUID = re.compile("[0-F]{8}-[0-F]{4}-[0-F]{4}-[0-F]{4}-[0-F]{12}", re.I)
    return bool(RE_UUID.match(key))

def get_settings_key():
    return r'SOFTWARE\{}\BackupAndRecovery\Settings'.format(acrort.common.BRAND_NAME)

def get_machine_settings_key():
    return get_settings_key() + r'\MachineManager'

def get_current_machine_id():
    return registry_read_string(get_machine_settings_key(), 'MMSCurrentMachineID')

def get_windows_product_installation_path():
    key = r'SOFTWARE\{}\Installer'.format(acrort.common.BRAND_NAME)
    return registry_read_string(key, 'TargetDir')

def get_product_installation_path():
    value = data[platform.system()]['product_path']
    if isinstance(value, str):
        return value
    return value(1)

def get_product_data_path():
    return os.path.join(acrort.fs.APPDATA_COMMON, acrort.common.BRAND_NAME)

def registry_read_string(key_name, value_name, open_hive=None):
    root_reg = acrort.registry.open_system_hive(hive=open_hive)
    if key_name not in root_reg.subkeys:
        acrort.common.make_logic_error(
            "Key '{}' not found. May be MMS service is not installed".format(key_name)).throw()
    key = root_reg.subkeys.open(key_name=key_name)
    if value_name not in key.values:
        acrort.common.make_logic_error(
            "Value '{}' not found. May be MMS service is not installed".format(value_name)).throw()
    value = key.values.open(value_name=value_name)
    return value.get(acrort.registry.TYPE_SZ)


def is_service_running(service_name):
    system = platform.system()
    if system == OS_WINDOWS:
        args = ['sc', 'query', service_name]
        ps = subprocess.Popen(args, stdout=subprocess.PIPE)
        output = ps.communicate()[0]
        return 'STOPPED' not in str(output)
    elif system in [OS_MAC, OS_LINUX]:
        ps = subprocess.Popen(('ps', 'aux'), stdout=subprocess.PIPE)
        output = ps.communicate()[0]
        return ('/' + service_name) in str(output)
    else:
        acrort.common.make_logic_error('Unsupported operating system: ' + system).throw()

def start_service(args, service_name):
    try:
        print('Executing command: {}'.format(' '.join(args)))

        subprocess.run(args, stdout=subprocess.DEVNULL, check=True)
    except Exception as e:
        print('Can\'t start %s service: %s', service_name, str(e))


def stop_service(args, service_name, is_service_running):
    try:
        print('Executing command: {}'.format(' '.join(args)))

        subprocess.run(args, stdout=subprocess.DEVNULL, check=True, timeout=60)
    except subprocess.CalledProcessError as e:
        acrort.common.make_logic_error(
            'Can\'t stop {} service with error: {}'.format(service_name, str(e))).throw()
    else:
        # Lookup for target process, wait if it is still here
        wait_reattempts = 10
        while wait_reattempts:
            time.sleep(10)
            if not is_service_running():
                break

            wait_reattempts = wait_reattempts - 1
            if not wait_reattempts:
                acrort.common.make_logic_error(
                    'Can\'t stop %s service, please stop it manually.'.format(service_name)).throw()


def is_mms_service_running():
    return is_service_running('mms')

def start_mms_service():
    start_service(data[platform.system()]['start_mms_args'], 'MMS')

def stop_mms_service():
    stop_service(data[platform.system()]['stop_mms_args'], 'MMS', is_mms_service_running)

def get_default_dml_database_path():
    return os.path.join(get_product_data_path(), 'BackupAndRecovery', 'MMSData', 'DML', 'F4CEEE47-042C-4828-95A0-DE44EC267A28.db3')

# Archives specs
def make_select_all_archives_spec():
    return [
        ('^Is', 'string', 'DMS::Cache::Archive'),
    ]

def make_select_archives_spec(archive_ids):
    ids = [[('', 'string', id)] for id in archive_ids]
    return [
        ('^Is', 'string', 'DMS::Cache::Archive'),
        ('.ID', 'string',''),
        ('.ID^ValueIn', 'complex_trait', [('', 'array', ids)]),
    ]

def make_select_foreign_archives_spec(machine_id, location_id, limit):
    options = [
        ('.LimitOptions', 'dword', limit),
    ]
    result = [
        ('^Is', 'string', 'DMS::Cache::Archive'),
        ('^Not', 'complex_trait', [
            ('.Attributes.MachineID', 'string', machine_id)
        ])
    ]

    if location_id:
        result += [('.Attributes.LocationID', 'guid', location_id)]

    return result, options

def make_select_machine_archives_spec(machine_id, location_id):
    result = [
        ('.Attributes.MachineID', 'string', ''),
        ('.Attributes.MachineID^Like', 'string', machine_id),
        ('^Is', 'string', 'DMS::Cache::Archive'),
    ]
    if location_id:
        result += [('.Attributes.LocationID', 'guid', location_id)]

    return result

# Backups specs
def make_select_all_backups_spec():
    return [
        ('^Is', 'string', 'DMS::Cache::Slice'),
    ]

def make_select_backups_spec(backup_ids):
    ids = [[('', 'string', id)] for id in backup_ids]
    return [
        ('^Is', 'string', 'DMS::Cache::Slice'),
        ('.ID', 'string',''),
        ('.ID^ValueIn', 'complex_trait', [('', 'array', ids)]),
    ]

def make_select_machine_backups_spec(machine_id, location_id):
    result = [
        ('^Is', 'string', 'DMS::Cache::Slice'),
        ('.Attributes.Location.LocationMachineID', 'string', ''),
        ('.Attributes.Location.LocationMachineID^Like', 'string', machine_id)
    ]
    if location_id:
        result += [('.Attributes.LocationID', 'guid', location_id)]

    return result

def make_select_foreign_backups_spec(machine_id, location_id, limit):
    options = [
        ('.LimitOptions', 'dword', limit),
    ]
    result = [
        ('^Is', 'string', 'DMS::Cache::Slice'),
        ('^Not', 'complex_trait', [
            ('.Attributes.Location.LocationMachineID', 'string', machine_id),
        ])
    ]
    if location_id:
        result += [('.Attributes.LocationID', 'guid', location_id)]

    return result, options


# Zmq acks specs
def make_select_channel_zmqgw_acks_spec(channel):
    return [
        ('^Is', 'string', 'ZmqGw::Ack'),
        ('.ID.Channel', 'string', channel),
    ]

def make_select_zmq_acks_spec_for_deletion(zmq_acks):
    ids = [[('', 'string', id)] for id in zmq_acks]
    return [
        ('^Is', 'string', 'ZmqGw::Ack'),
        ('.ID.Key', 'string',''),
        ('.ID.Key^ValueIn', 'complex_trait', [('', 'array', ids)]),
    ]

def make_select_zmq_acks_spec(channel, limit):
    options = [
        ('.LimitOptions', 'dword', limit),
    ]
    return [
        ('^Is', 'string', 'ZmqGw::Ack'),
        ('.ID.Channel', 'string', channel),
    ], options


def get_objects(dml, pattern, options=None):
    if options:
        return dml.select(acrort.dml.ViewSpec(acrort.plain.Unit(flat=pattern),
            acrort.plain.Unit(flat=options)))
    return dml.select(acrort.dml.ViewSpec(acrort.plain.Unit(flat=pattern)))

def get_objects_count(dml, pattern):
    options = [
        ('.Counter.CounterObjectTemplate.ID', 'string', 'Count'),
        ('.Counter.CounterObjectTemplate.ID^PrimaryKey', 'nil', None)
    ]
    return dml.select1(acrort.dml.ViewSpec(acrort.plain.Unit(flat=pattern), acrort.plain.Unit(flat=options))).CounterValue.ref

def print_progress(current, max):
    sys.stdout.write('{} of {}\r'.format(current, max))


def get_archives_count(dml, machine_id, location_id):
    all_archives = get_objects_count(dml, make_select_all_archives_spec())
    machine_archives = get_objects_count(dml, make_select_machine_archives_spec(machine_id, location_id))
    zmq_acks = get_objects_count(dml, make_select_channel_zmqgw_acks_spec('Archive'))
    return all_archives, machine_archives, all_archives - machine_archives, zmq_acks

def cleanup_archives(dml, machine_id, location_id, all_archives_count):
    counter = 0
    foreign_archives = ['dummy']
    while foreign_archives:
        print_progress(counter, all_archives_count)
        foreign_archives = get_objects(dml, *make_select_foreign_archives_spec(machine_id, location_id, CHUNK_SIZE))
        if foreign_archives:
            ids = [item.ID.ref for item in foreign_archives]
            dml.delete(pattern=acrort.plain.Unit(flat=make_select_archives_spec(ids)))
            counter += len(foreign_archives)
            print_progress(counter, all_archives_count)


def get_backups_count(dml, machine_id, location_id):
    all_backups = get_objects_count(dml, make_select_all_backups_spec())
    machine_backups = get_objects_count(dml, make_select_machine_backups_spec(machine_id, location_id))
    zmq_acks = get_objects_count(dml, make_select_channel_zmqgw_acks_spec('Slice'))
    return all_backups, machine_backups, all_backups - machine_backups, zmq_acks

def cleanup_backups(dml, machine_id, location_id, all_backups_count):
    counter = 0
    foreign_backups = ['dummy']
    print_progress(counter, all_backups_count)
    while foreign_backups:
        foreign_backups = get_objects(dml, *make_select_foreign_backups_spec(machine_id, location_id, CHUNK_SIZE))
        if foreign_backups:
            ids = [item.ID.ref for item in foreign_backups]
            dml.delete(pattern=acrort.plain.Unit(flat=make_select_backups_spec(ids)))
            counter += len(foreign_backups)
            print_progress(counter, all_backups_count)


def cleanup_zmqgw_acks(dml, all_acks_count):
    counter = 0
    print_progress(counter, all_acks_count)
    for channel in ['Archive', 'Slice']:
        acks = ['dummy']
        while acks:
            acks = get_objects(dml, *make_select_zmq_acks_spec(channel, CHUNK_SIZE))
            if acks:
                ids = [item.ID.Key.ref for item in acks]
                dml.delete(pattern=acrort.plain.Unit(flat=make_select_zmq_acks_spec_for_deletion(ids)))
                counter += len(acks)
                print_progress(counter, all_acks_count)


def main():
    system = platform.system()
    if system not in [OS_WINDOWS, OS_LINUX, OS_MAC]:
        acrort.common.make_logic_error('Unsupported operating system: ' + system).throw()
        
    parser = argparse.ArgumentParser(description='Cleanup DML DB from foreign archives and backups')
    parser.add_argument(
        '-c', '--cleanup', required=False, action="store_true",
        help='Flag whether to cleanup DML DB from foreign archives and backups')
    parser.add_argument(
        '-d', '--db-path', required=False, nargs=1,
        help='Full path where DML database is placed, product path will be used if it is not specified')
    parser.add_argument(
        '-m', '--machine-id', required=False, nargs=1,
        help='Machine identifier in form <GUID>, will be used from the current MMS installation if it is not specified')
    parser.add_argument(
        '-b', '--backups', required=False, action="store_true",
        help='Flag whether to report number of foreign archives and backups only')
    parser.add_argument(
        '-a', '--acks', required=False, action="store_true",
        help='Flag whether to report number of ZMQ acks only')
    parser.add_argument(
        '-l', '--location-id', required=False, nargs=1,
        help='Location identifier in form <GUID>, will be used as additional filter for archive and backups deletion')

    args = parser.parse_args()

    db_path = get_default_dml_database_path()
    if args.db_path:
        db_path = args.db_path[0]

    silent_mode = args.backups or args.acks
    if not silent_mode:
        print("DML database used at: {}".format(db_path))

    machine_id = None
    if args.machine_id:
        machine_id = args.machine_id[0]
    if not machine_id:
        machine_id = get_current_machine_id()
    if not silent_mode:
        print("Machine to preserve archives and backups from: {}".format(machine_id))

    machine_id = machine_id.upper()
    if not is_guid(machine_id):
        print("Machine identifier error: invalid GUID format: {}".format(machine_id))
        return

    location_id = None
    if args.location_id:
        location_id = args.location_id[0]

    cleanup = args.cleanup
    if cleanup and not args.db_path and is_mms_service_running():
        print("Stopping MMS service...")
        stop_mms_service()
        print("Done.\n")

    connection_string = 'sqlite-v2://{}#limit_statement_cache'.format(db_path) 
    conn = acrort.dml.open_database(connection_string)

    archives_count, machine_archives, foreign_archives, zmq_arc_acks = get_archives_count(conn.dml, machine_id, location_id)
    backups_count, machine_backups, foreign_backups, zmq_bckp_acks = get_backups_count(conn.dml, machine_id, location_id)
    if args.backups:
        print(foreign_archives + foreign_backups)
        return
    elif args.acks:
        print(zmq_arc_acks + zmq_bckp_acks)
        return

    print("Statistics (before cleanup):")
    print("Total archives: {}, machine archives: {}, foreign archives: {}, zmq acks: {}".format(archives_count, machine_archives, foreign_archives, zmq_arc_acks))
    print("Total backups: {}, machine backups: {}, foreign backups: {}, zmq acks: {}".format(backups_count, machine_backups, foreign_backups, zmq_bckp_acks))

    if cleanup:
        if foreign_archives:
            print("\nCleanup foreign archives...")
            cleanup_archives(conn.dml, machine_id, location_id, archives_count)
            print("\nDone.\n")

        if foreign_backups:
            print("\nCleanup foreign backups...")
            cleanup_backups(conn.dml, machine_id, location_id, backups_count)
            print("\nDone.\n")

        if zmq_arc_acks + zmq_bckp_acks:
            print("\nCleanup zmq acks...")
            cleanup_zmqgw_acks(conn.dml, zmq_arc_acks + zmq_bckp_acks)
            print("\nDone.\n")

        print("Statistics (after cleanup):")
        archives_count, machine_archives, foreign_archives, zmq_arc_acks = get_archives_count(conn.dml, machine_id, location_id)
        backups_count, machine_backups, foreign_backups, zmq_bckp_acks = get_backups_count(conn.dml, machine_id, location_id)
        print("Total archives: {}, machine archives: {}, foreign archives: {}, zmq acks: {}".format(archives_count, machine_archives, foreign_archives, zmq_arc_acks))
        print("Total backups: {}, machine backups: {}, foreign backups: {}, zmq acks: {}".format(backups_count, machine_backups, foreign_backups, zmq_bckp_acks))

    if cleanup and not args.db_path:
        print("\nStarting MMS service...")
        start_mms_service()
        print("Done.")

    print("\nSuccessfully finished.")


if __name__ == '__main__':
    import acrobind
    exit(acrobind.interruptable_safe_execute(main))

Youez - 2016 - github.com/yon3zu
LinuXploit