Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Commit

Permalink
Start tidying up interface
Browse files Browse the repository at this point in the history
  • Loading branch information
richfitz committed Oct 20, 2023
1 parent c3570d4 commit 4563da7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
17 changes: 16 additions & 1 deletion src/privateer2/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
privateer2 [options] keygen (<name> | --all)
privateer2 [options] configure <name>
privateer2 [options] check [--connection]
privateer2 [options] backup <volume> [--server=NAME]
privateer2 [options] restore <volume> [--server=NAME] [--source=NAME]
privateer2 [options] export <volume> [--to-dir=PATH] [--source=NAME]
privateer2 [options] import <tarfile> <volume>
privateer2 [options] server (start | stop | status)
privateer2 [options] schedule (start | stop | status)
Expand All @@ -24,7 +27,10 @@
Note that the 'import' subcommand is quite different and does not
interact with the configuration; it will reject options '--as' and
'--path'. If 'volume' exists already, it will fail, so this is
fairly safe.
fairly safe. If running export with '--source=local' then the
configuration is not read - this can be used anywhere to create a
tar file of a local volume, which is suitable for importing with
'import'.
The server and schedule commands start background containers that
run forever (with the 'start' option). Check in on them with
Expand Down Expand Up @@ -131,6 +137,15 @@ def _parse_opts(opts):
tarfile=opts["<tarfile>"],
dry_run=dry_run,
)
elif opts["export"] and opts["--source"] == "local":
_dont_use("--as", opts, "export --local")
_dont_use("--path", opts, "export --local")
return Call(
export_tar_local,
volume=opts["<volume>"],
to_dir=opts["--to-dir"],
dry_run=dry_run,
)

path_config = _path_config(opts["--path"])
root_config = os.path.dirname(path_config)
Expand Down
46 changes: 33 additions & 13 deletions src/privateer2/tar.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os

import docker
from privateer2.config import find_source
from privateer2.check import check
from privateer2.config import find_source
from privateer2.util import (
isotimestamp,
mounts_str,
Expand All @@ -14,25 +14,44 @@

def export_tar(cfg, name, volume, *, to_dir=None, source=None, dry_run=False):
machine = check(cfg, name, quiet=True)
# TODO: we should be able to export a truely local volume too;
# this one probably can run a few ways.
#
# TODO: check here that volume is either local, or that it is a
# backup target for anything.
# backup target for anything that we look after. If local, we need
# to use export_tar_local, and not this function.
source = find_source(cfg, volume, source)
if not source:
return export_tar_local(volume, to_dir=to_dir, dry_run=dry_run)

image = f"mrcide/privateer-client:{cfg.tag}"
if to_dir is None:
export_path = os.getcwd()
else:
export_path = os.path.abspath(to_dir)
mounts = [
docker.types.Mount("/export", export_path, type="bind"),
docker.types.Mount(
"/export", os.path.abspath(to_dir or ""), type="bind"
),
docker.types.Mount(
"/privateer", machine.data_volume, type="volume", read_only=True
),
]
tarfile = f"{source}-{volume}-{isotimestamp()}.tar"
working_dir = f"/privateer/{source}/{volume}"
src = f"/privateer/{source}/{volume}"
_run_tar_create(image, mounts, src, tarfile, dry_run)


def export_tar_local(volume, *, to_dir=None, dry_run=False):
if not volume_exists(volume):
msg = f"Volume '{volume}' does not exist"
raise Exception(msg)
image = "alpine"
mounts = [
docker.types.Mount(
"/export", os.path.abspath(to_dir or ""), type="bind"
),
docker.types.Mount("/privateer", volume, type="volume", read_only=True),
]
tarfile = f"{volume}-{isotimestamp()}.tar"
src = "/privateer"
_run_tar_create(image, mounts, src, tarfile, dry_run)


def _run_tar_create(image, mounts, src, tarfile, dry_run=True):
command = ["tar", "-cpvf", f"/export/{tarfile}", "."]
if dry_run:
cmd = [
Expand All @@ -41,7 +60,7 @@ def export_tar(cfg, name, volume, *, to_dir=None, source=None, dry_run=False):
"--rm",
*mounts_str(mounts),
"-w",
working_dir,
src,
image,
*command,
]
Expand All @@ -67,7 +86,7 @@ def export_tar(cfg, name, volume, *, to_dir=None, source=None, dry_run=False):
image,
command=command,
mounts=mounts,
working_dir=working_dir,
working_dir=src,
)
print("Taking ownership of file")
take_ownership(tarfile, export_path)
Expand All @@ -80,6 +99,7 @@ def import_tar(volume, tarfile, *, dry_run=False):
raise Exception(msg)
if not os.path.exists(tarfile):
msg = f"Input file '{tarfile}' does not exist"
raise Exception(msg)

image = "alpine"
tarfile = os.path.abspath(tarfile)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def test_can_find_appropriate_source():
def test_can_find_appropriate_source_if_local():
cfg = read_config("example/simple.json")
cfg.volumes[0].local = True
find_source(cfg, "data", None)
assert find_source(cfg, "data", None) is None
msg = "'data' is a local source, so 'source' must be empty"
with pytest.raises(Exception, match=msg):
find_source(cfg, "data", "bob")
Expand Down

0 comments on commit 4563da7

Please sign in to comment.