web-dev-qa-db-fra.com

Format d'état de la collecte duplicity

Se demandant si je peux avoir une main ici pour faciliter la sortie de la commande duplicity collection-status MYPATH

Mon objectif ultitime est de créer un script "restaurer" qui utilisera cette commande et créera une liste sélectionnable de sauvegardes à restaurer.

En ce moment, mon code est comme suit:

    # get the backups information
    _t=`duplicity collection-status $1`

    # split the collection based on new lines
    IFS=$'\n' _arr=($_t)

    # find the length of the array
    _arr_len=${#_arr[@]}      

    # we only want the last set of lines, minus the last 2 lines
    _end=`expr $_arr_len - 2`

    # loop over our resulting set and echo out the line
    _idx=1
    _menu_idx=1
    _ret_arr=()

    # make sure there are actually backups created
    if [[ -z ${_arr[14]} ]]; then
        # it doesnt exist, show a message and exit
        echo 
        echo '--------------------------------------------------------------------';
        echo 'There are no backups for that account/app'
        echo 'Please create the account, and make sure it matches the restore'
        echo 'Account and App names'
        echo '--------------------------------------------------------------------';
        echo 
        exit 1;
    fi;

    echo 
    echo '--------------------------------------------------------------------';
    echo "- Select a restore point: "

    for _l in ${_arr[@]}; do
        if [ $_idx -ge 14 -a $_idx -le $_end ]; then

            IFS=$' ' _temp_arr=($_l)
            _d_string=${_temp_arr[1]}" "${_temp_arr[2]}" "${_temp_arr[3]}" "${_temp_arr[4]}" "${_temp_arr[5]}
            _ret_arr+=( "$_d_string" )
            # Tue Aug 27 10:59:43 2019
            echo $_menu_idx") "$_d_string;

            ((_menu_idx=_menu_idx+1))
        fi;
        ((_idx=_idx+1))
    done
    read n

    # get the value of the selected item
    _t=${_ret_arr[$n-1]};

    # make sure the selection is valid
    if [[ -z $_t ]]; then
        echo "You selected an invalid restore point.  Please try again"
        exit 1;
    fi;

    echo 

    # convert the selected value to a Epoch date and return it
    _ret_date=$(date -d "${_t}" +"%s");

Et bien que cela semble faire le tour à mes fins, j'ai trouvé sur quelques serveurs différents que je finis avec un texte "extra" avant et après, la liste n'est donc pas toujours des points de sauvegarde. Un exemple de sortie est structuré un peu comme ceci:

root@sp-stage1:~# duplicity collection-status $_dest/$_Host/apps/aats/aats/
Synchronizing remote metadata to local cache...
Copying duplicity-full-signatures.20190903T134927Z.sigtar.gz to local cache.
Copying duplicity-full.20190903T134927Z.manifest to local cache.
Copying duplicity-inc.20190903T134927Z.to.20190903T162118Z.manifest to local cache.
Copying duplicity-inc.20190903T162118Z.to.20190904T050005Z.manifest to local cache.
Copying duplicity-inc.20190904T050005Z.to.20190905T050004Z.manifest to local cache.
Copying duplicity-inc.20190905T050004Z.to.20190906T050005Z.manifest to local cache.
Copying duplicity-inc.20190906T050005Z.to.20190907T050005Z.manifest to local cache.
Copying duplicity-inc.20190907T050005Z.to.20190908T050004Z.manifest to local cache.
Copying duplicity-new-signatures.20190903T134927Z.to.20190903T162118Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190903T162118Z.to.20190904T050005Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190904T050005Z.to.20190905T050004Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190905T050004Z.to.20190906T050005Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190906T050005Z.to.20190907T050005Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190907T050005Z.to.20190908T050004Z.sigtar.gz to local cache.
Last full backup date: Tue Sep  3 09:49:27 2019
Collection Status
-----------------
Connecting with backend: BackendWrapper
Archive dir: /home/ubuntu/.cache/duplicity/6a9fb8e3df936035e1be5ede96c0d7a7

Found 0 secondary backup chains.

Found primary backup chain with matching signature chain:
-------------------------
Chain start time: Tue Sep  3 09:49:27 2019
Chain end time: Sun Sep  8 01:00:04 2019
Number of contained backup sets: 7
Total number of contained volumes: 8
 Type of backup set:                            Time:      Num volumes:
                Full         Tue Sep  3 09:49:27 2019                 2
         Incremental         Tue Sep  3 12:21:18 2019                 1
         Incremental         Wed Sep  4 01:00:05 2019                 1
         Incremental         Thu Sep  5 01:00:04 2019                 1
         Incremental         Fri Sep  6 01:00:05 2019                 1
         Incremental         Sat Sep  7 01:00:05 2019                 1
         Incremental         Sun Sep  8 01:00:04 2019                 1
-------------------------
No orphaned or incomplete backup sets found.

Dans cet exemple spécifique, le menu produit est comme ceci:

--------------------------------------------------------------------
- Select a restore point:
1) of contained backup sets: 8
2) number of contained volumes: 9
3) of backup set: Time: Num
4) Tue Sep 3 09:49:27 2019
5) Tue Sep 3 12:21:18 2019
6) Wed Sep 4 01:00:05 2019
7) Thu Sep 5 01:00:04 2019
8) Fri Sep 6 01:00:05 2019
9) Sat Sep 7 01:00:05 2019
10) Sun Sep 8 01:00:04 2019
11) Sun Sep 8 09:33:26 2019

Quand cela devrait vraiment être:

--------------------------------------------------------------------
- Select a restore point:
1) Tue Sep 3 09:49:27 2019
2) Tue Sep 3 12:21:18 2019
3) Wed Sep 4 01:00:05 2019
4) Thu Sep 5 01:00:04 2019
5) Fri Sep 6 01:00:05 2019
6) Sat Sep 7 01:00:05 2019
7) Sun Sep 8 01:00:04 2019
8) Sun Sep 8 09:33:26 2019

(Oui Les doubles sauvegardes du 8 septembre sont correctes ... pour l'instant)

Alors ... Je dois faire mal à montrer ces quelques lignes supplémentaires ... Comment puis-je résoudre ce problème, et où je vais vraiment mal?

(serait tellement plus facile si je pouvais simplement passer un --json Drapeau, mais cela n'a pas encore été mis en œuvre ...)

2
Kevin

Où dois-je vraiment mal?

if [ $_idx -ge 14 -a $_idx -le $_end ]

L'approche complète de l'analyse de la production en comptant des nombres spécifiques de lignes non vides à partir du début et de la fin. Il est très fragile et ne peut évidemment pas faire face à un nombre différent de lignes renvoyées avant et après ceux que vous vouliez.

Votre entrée fournie de Duplicity a beaucoup plus de 3 de plus que vos 14 lignes non vides attendues avant que les données recherchées. Une possibilité est que cette entrée aurait pu être un mélange de stdout et de StdoutR, alors que votre code ne lit que stdout. Cependant, je note que 14 lignes non vierges n'excluent pas les lignes Copying. Comme l'entrée de la duplicité ne correspond également pas à la sortie attendue ou réelle des dates de sauvegarde, je suppose qu'il n'y avait que trois Copying lignes dans l'entrée réelle pour votre exemple.

Si tel est le cas, et si le format de la sortie est par sinon la même chose dans tous les cas, votre code pourrait fonctionner si duplicity collection-status est exécuté deux fois sans une nouvelle sauvegarde entre les deux. Mais cela suppose également qu'il n'y aura pas de nouvelles surprises dans la production, y compris des changements possibles dans une version future de la duplicité.

Plutôt que de compter, numérisez les lignes commençant par "plein" ou "incrémental" à la place. La sortie supplémentaire est moins probable et c'est aussi beaucoup plus simple.

C'est une habitude importante pour toujours double citation "$variables" Sauf lorsque vous êtes intentionnellement des mots (par exemple, vos lignes IFS). Si vous ne faites que le minimum, il est facile d'être attrapé par des mots inattendus plus tard sur les entrées futures que vous n'aviez pas initialement prévue.

En outre, le Bash intégré select (voir help select) est un moyen facile de gérer des menus.

# get the backups information
_t=`duplicity collection-status "$1"`

# split the collection based on new lines
IFS=$'\n' _arr=($_t)

# loop over our resulting set and select lines
_ret_arr=()
for _l in "${_arr[@]}"; do
    IFS=$' ' _temp_arr=($_l)
    if [ Full = "${_temp_arr[0]}" -o Incremental = "${_temp_arr[0]}" ]; then
        _d_string="${_temp_arr[1]} ${_temp_arr[2]} ${_temp_arr[3]} ${_temp_arr[4]} ${_temp_arr[5]}"
        _ret_arr+=( "$_d_string" )
    fi;
done

echo 
echo '--------------------------------------------------------------------';
# make sure there are actually backups created, i.e. at least one line matched
if [[ -z "${_ret_arr[0]}" ]]; then
    # it doesnt exist, show a message and exit
    echo 'There are no backups for that account/app'
    echo 'Please create the account, and make sure it matches the restore'
    echo 'Account and App names'
    echo '--------------------------------------------------------------------';
    echo 
    exit 1;
fi

echo "- Select a restore point: "
select _t in "${_ret_arr[@]}"; do
    # will keep asking until valid value given
    [ -n "$_t" ] && break
done

echo 

# convert the selected value to a Epoch date and return it
_ret_date=$(date -d "${_t}" +"%s")
1
Martin Thornton