Skip to content

Backup and restore Ursula config#2682

Closed
piotr-roslaniec wants to merge 10 commits intonucypher:mainfrom
piotr-roslaniec:ursula-backup#1992
Closed

Backup and restore Ursula config#2682
piotr-roslaniec wants to merge 10 commits intonucypher:mainfrom
piotr-roslaniec:ursula-backup#1992

Conversation

@piotr-roslaniec
Copy link
Copy Markdown
Contributor

@piotr-roslaniec piotr-roslaniec commented May 3, 2021

Type of PR:

  • Bugfix
  • Feature
  • Documentation
  • Other

Required reviews:

  • 1
  • 2
  • 3

What this does:

  • Add CLI commands for Ursula backup, ursula backup and ursula restore.
  • Backups are encrypted ZIP files protected by a password.
  • Both commands have the same flags, but the actual behavior depends on the command used. For example, ursula backup --worker-path would denote file sources used to create a backup file. On the other hand, ursula restore --worker-path denotes the destination where unpacked backup files will be stored.
$ nucypher ursula backup \
   --worker-path <path> \ # set to default 
   --keystore-path <path> \   # set to default
   --backup-path <path> \ # required
   --password <str> \ # required
   --overwrite <bool> \ # optional

$ nucypher ursula restore \
   --worker-path <path> \ # set to default 
   --keystore-path <path> \   # set to default
   --backup-path <path> \ # required
   --password <str> \ # required
   --overwrite <bool> \ # optional
  • Backup archive has a following structure:
$ tree -L 3 restored
restored
├── keystore
│   └── keystore.json
└── worker
    └── nucypher
        ├── cards
        ├── keyring
        ├── known_nodes
        ├── ursula.db
        └── ursula.json

Issues fixed/closed:

Why it's needed:

Explain how this PR fits in the greater context of the NuCypher Network.
E.g., if this PR address a nucypher/productdev issue, let reviewers know!

Notes for reviewers:

@piotr-roslaniec piotr-roslaniec changed the title [WIP] Backup and restore Ursula config Backup and restore Ursula config May 6, 2021
@piotr-roslaniec piotr-roslaniec marked this pull request as ready for review May 6, 2021 08:46
@KPrasch
Copy link
Copy Markdown
Member

KPrasch commented May 14, 2021

If there are multiple ursulas on a system, how does the backup/restore functionality determine which database to use? Are we making this distinction at all, or are we inadvertently reusing a single DB for all ursulas on one host?

@piotr-roslaniec
Copy link
Copy Markdown
Contributor Author

@KPrasch There is no distinction made between databases, backups are made only based on the path to the worker directory. But this is something that can be improved by reading db_filepath from the Ursula config file, and rewriting it accordingly after backup is restored.

pychalk==2.0.1
pycparser==2.20; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
pycryptodome==3.9.9
pycryptodomex==3.10.1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if there can be any implication of having both pycryptodome and pycryptodomex. It seems the x version was released to avoid interference with the pycrypto package, which we don't use anyway (https://www.pycryptodome.org/en/latest/src/introduction.html?highlight=pycryptodomex#pycryptodome). It seems in our case we can potentially use both, but probably it's a dependency issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use both of those packages as indirect dependencies of eth-hash and pyzipper. AFAIK there should be no issues with dependency shadowing, even if we start using them directly, as they have different namespaces (base package names).

@derekpierre
Copy link
Copy Markdown
Member

We'll also need to add some documentation.

Copy link
Copy Markdown
Member

@derekpierre derekpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff - just some minor documentation edits

with pyzipper.AESZipFile(backup_options.backup_path) as zf:
zf.setpassword(backup_options.password)
zf.setencryption(**BACKUP_ENCRYPTION_SETTINGS)
_extract_zf(emitter, zf, KEYSTORE_ARCHIVE_ROOT, backup_options.keystore_path, backup_options.overwrite)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 - "extract" looks good there.

piotr-roslaniec and others added 2 commits June 1, 2021 16:52
Co-authored-by: Derek Pierre <derek.pierre@gmail.com>
def _prompt_overwrite(path: Path, force: bool):
if path.exists():
prompt = f"Path already exists: {path.absolute()}"
if force:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💥

Copy link
Copy Markdown
Member

@derekpierre derekpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having some issues with restore and pre-existing folders.

derek @ Dereks-MacBook-Pro-2 ~/Documents/Github/repos/forks/piotr/nucypher
 [37] → nucypher ursula backup --password llamallama --force
WARNING: Force is enabled
Path already exists: /Users/derek/Documents/Github/repos/forks/piotr/nucypher/ursula-backup.zip - Overwriting.
Wrote /Users/derek/Library/Application Support/nucypher
Wrote /Users/derek/Library/Ethereum/keystore
Backup created at /Users/derek/Documents/Github/repos/forks/piotr/nucypher/ursula-backup.zip


(nucypher) (base)
derek @ Dereks-MacBook-Pro-2 ~/Documents/Github/repos/forks/piotr/nucypher
 [38] → ls -l worker keystore
keystore:
total 0
drwxr-xr-x  3 derek  staff  96  3 Jun 09:29 keystore

worker:
total 0
drwxr-xr-x  3 derek  staff  96  3 Jun 09:23 worker


(nucypher) (base)
derek @ Dereks-MacBook-Pro-2 ~/Documents/Github/repos/forks/piotr/nucypher
 [39] → nucypher ursula restore --password llamallama --worker-path ./worker --keystore-path ./keystore/ --backup-path ./ursula-backup.zip
Path already exists: /Users/derek/Documents/Github/repos/forks/piotr/nucypher/keystore - Overwrite? [y/N]: y
Traceback (most recent call last):
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/bin/nucypher", line 33, in <module>
    sys.exit(load_entry_point('nucypher', 'console_scripts', 'nucypher')())
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/derek/Documents/Github/repos/forks/piotr/nucypher/nucypher/cli/options.py", line 169, in wrapper
    return func(**kwargs)
  File "/Users/derek/Documents/Github/repos/forks/piotr/nucypher/nucypher/cli/options.py", line 169, in wrapper
    return func(**kwargs)
  File "/Users/derek/Documents/Github/repos/forks/piotr/nucypher/nucypher/cli/commands/ursula.py", line 600, in restore
    _extract_zf(emitter, zf, KEYSTORE_ARCHIVE_ROOT, backup_options.keystore_path, backup_options.force)
  File "/Users/derek/Documents/Github/repos/forks/piotr/nucypher/nucypher/cli/commands/ursula.py", line 616, in _extract_zf
    shutil.move(str(archive_path.absolute()), str(destination_path.absolute()))
  File "/Users/derek/.local/share/virtualenvs/nucypher-GD4zeyIP/lib/python3.7/shutil.py", line 564, in move
    raise Error("Destination path '%s' already exists" % real_dst)
shutil.Error: Destination path '/Users/derek/Documents/Github/repos/forks/piotr/nucypher/keystore/keystore' already exists

@KPrasch KPrasch mentioned this pull request Jun 16, 2021
Copy link
Copy Markdown
Member

@KPrasch KPrasch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great overall. If we're going to support nucypher ursula restore I think we need to support restoration from mnemonic phrase as well as file-based backups.

@piotr-roslaniec piotr-roslaniec deleted the ursula-backup#1992 branch September 6, 2021 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants