IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
Browse Source

Add focker volume protect/unprotect.

master
parent
commit
000397a289
4 changed files with 107 additions and 9 deletions
  1. +11
    -1
      focker/focker.py
  2. +15
    -1
      focker/volume.py
  3. +24
    -5
      focker/zfs.py
  4. +57
    -2
      tests/test_volume.py

+ 11
- 1
focker/focker.py View File

@@ -24,7 +24,9 @@ from .volume import command_volume_create, \
command_volume_untag, \
command_volume_remove, \
command_volume_set, \
command_volume_get
command_volume_get, \
command_volume_protect, \
command_volume_unprotect
import sys
from .zfs import zfs_init
from .jail import command_jail_create, \
@@ -209,6 +211,14 @@ def create_parser():
parser.add_argument('reference', type=str)
parser.add_argument('properties', type=str, nargs=argparse.REMAINDER)
parser = ListForwarder([subparsers.add_parser(cmd) for cmd in ['protect']])
parser.set_defaults(func=command_volume_protect)
parser.add_argument('references', type=str, nargs='+')
parser = ListForwarder([subparsers.add_parser(cmd) for cmd in ['unprotect']])
parser.set_defaults(func=command_volume_unprotect)
parser.add_argument('references', type=str, nargs='+')
# compose
subparsers = ListForwarder([ subparsers_top.add_parser(cmd).add_subparsers(dest='L2_command') \
for cmd in ['compose', 'comp', 'c'] ])


+ 15
- 1
focker/volume.py View File

@@ -51,7 +51,7 @@ def command_volume_remove(args):
try:
name, _ = zfs_find(ref, focker_type='volume')
print('Removing:', name)
zfs_run(['zfs', 'destroy', '-r', '-f', name])
zfs_destroy(name)
except:
if not args.force:
raise
@@ -71,3 +71,17 @@ def command_volume_get(args):
res = zfs_parse_output(['zfs', 'get', '-H', ','.join(args.properties), name])
res = [ [ args.properties[i], a[2] ] for i, a in enumerate(res) ]
print(tabulate(res, headers=['Property', 'Value']))
def command_volume_protect(args):
for ref in args.references:
name, _ = zfs_find(ref, focker_type='volume')
print('Protecting:', name)
zfs_protect(name)
def command_volume_unprotect(args):
for ref in args.references:
name, _ = zfs_find(ref, focker_type='volume')
print('Unprotecting:', name)
zfs_unprotect(name)

+ 24
- 5
focker/zfs.py View File

@@ -83,7 +83,7 @@ def zfs_prune(focker_type='image'):
again = True
while again:
again = False
lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,focker:tags,origin,name', '-H', '-r', poolname + '/focker/' + focker_type + 's'])
lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,focker:tags,origin,name,focker:protect', '-H', '-r', poolname + '/focker/' + focker_type + 's'])
used = set()
for r in lst:
if r[2] == '-':
@@ -92,10 +92,29 @@ def zfs_prune(focker_type='image'):
for r in lst:
if r[0] == '-' or r[1] != '-':
continue
if r[3] not in used:
print('Removing:', r[3])
zfs_run(['zfs', 'destroy', '-r', '-f', r[3]])
again = True
if r[3] in used:
continue
if r[4] != '-':
print('%s is protected against removal' % r[3])
continue
print('Removing:', r[3])
zfs_run(['zfs', 'destroy', '-r', '-f', r[3]])
again = True
def zfs_destroy(name):
lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:protect', name])
if lst[0][2] != '-':
raise RuntimeError('%s is protected against removal' % name)
zfs_run(['zfs', 'destroy', '-r', '-f', name])
def zfs_protect(name):
zfs_run(['zfs', 'set', 'focker:protect=on', name])
def zfs_unprotect(name):
zfs_run(['zfs', 'inherit', '-r', 'focker:protect', name])
def zfs_clone(name, target_name):


+ 57
- 2
tests/test_volume.py View File

@@ -7,13 +7,19 @@ from focker.volume import command_volume_create, \
command_volume_untag, \
command_volume_remove, \
command_volume_set, \
command_volume_get
command_volume_get, \
command_volume_protect, \
command_volume_unprotect
from focker.zfs import zfs_find, \
zfs_mountpoint, \
zfs_exists, \
zfs_parse_output
zfs_parse_output, \
zfs_destroy, \
zfs_prune, \
zfs_run
import os
import focker.volume
import focker.zfs
def test_command_volume_create():
@@ -162,3 +168,52 @@ def test_command_volume_get(monkeypatch):
assert headers == [ 'Property', 'Value' ]
# assert lst == ['on', '1G']
subprocess.check_output(['focker', 'volume', 'remove', 'test-command-volume-get'])
def test_command_volume_protect(monkeypatch):
subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-protect'])
subprocess.check_output(['focker', 'volume', 'create', '-t', 'test-command-volume-protect'])
args = lambda: 0
args.references = ['test-command-volume-protect']
command_volume_protect(args)
name, sha256 = zfs_find('test-command-volume-protect', focker_type='volume')
mountpoint = zfs_mountpoint(name)
lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:protect', name])
assert len(lst) == 1
assert lst[0][2] == 'on'
with pytest.raises(RuntimeError):
zfs_destroy(name)
subprocess.check_output(['focker', 'volume', 'untag', 'test-command-volume-protect'])
lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:tags', name])
assert len(lst) == 1
assert lst[0][2] == '-'
n_called = 0
def fake_run(*args, **kwargs):
nonlocal n_called
n_called += 1
return zfs_run(*args, **kwargs)
monkeypatch.setattr(focker.zfs, 'zfs_run', fake_run)
zfs_prune(focker_type='volume')
assert not n_called == 1
with pytest.raises(subprocess.CalledProcessError):
subprocess.check_output(['focker', 'volume', 'remove', sha256])
subprocess.check_output(['zfs', 'destroy', '-r', '-f', name])
assert not zfs_exists(name)
assert not os.path.exists(mountpoint)
def test_command_volume_unprotect():
subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-unprotect'])
subprocess.check_output(['focker', 'volume', 'create', '-t', 'test-command-volume-unprotect'])
subprocess.check_output(['focker', 'volume', 'protect', 'test-command-volume-unprotect'])
name, _ = zfs_find('test-command-volume-unprotect', focker_type='volume')
lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:protect', name])
assert len(lst) == 1
assert lst[0][2] == 'on'
args = lambda: 0
args.references = ['test-command-volume-unprotect']
command_volume_unprotect(args)
lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:protect', name])
assert len(lst) == 1
assert lst[0][2] == '-'
subprocess.check_output(['focker', 'volume', 'remove', 'test-command-volume-unprotect'])

Loading…
Cancel
Save