|
@@ -34,6 +34,7 @@ import json
|
|
|
import os
|
|
|
import re
|
|
|
import select
|
|
|
+import shlex
|
|
|
import shutil
|
|
|
import subprocess
|
|
|
import sys
|
|
@@ -98,6 +99,20 @@ class DockerImage:
|
|
|
repo_digest, = re.search(rb'^Digest: (sha\S+:\S+)$', out.getvalue(), re.MULTILINE).groups()
|
|
|
return cls('{}@{}'.format(image, repo_digest.decode()))
|
|
|
|
|
|
+ def run(self, detach=False, publish_ports=[], args=[], caps=[]):
|
|
|
+ params = ['sudo', 'docker', 'run', '--rm']
|
|
|
+ if detach:
|
|
|
+ params.append('--detach')
|
|
|
+ else:
|
|
|
+ params.extend(['--interactive', '--tty'])
|
|
|
+ params.extend('--publish=' + ':'.join([str(a) for a in p]) for p in publish_ports)
|
|
|
+ params.extend(['--security-opt=no-new-privileges', '--cap-drop=all'])
|
|
|
+ params.extend(['--cap-add={}'.format(c) for c in caps])
|
|
|
+ params.append(self._id)
|
|
|
+ params.extend(args)
|
|
|
+ sys.stderr.write('{}\n'.format(shlex_join(params)))
|
|
|
+ subprocess.run(params, check=True)
|
|
|
+
|
|
|
class StdoutTee:
|
|
|
|
|
|
def __init__(self, sink):
|
|
@@ -169,20 +184,6 @@ def docker_build(dockerfile):
|
|
|
assert not image_id is None, 'could not determine image id'
|
|
|
return image_id.decode(sys.stdout.encoding)
|
|
|
|
|
|
-def docker_run(image_id=None, dockerfile=None, caps=[]):
|
|
|
- assert image_id is None or dockerfile is None, \
|
|
|
- 'either pass kwarg image_id or dockerfile'
|
|
|
- if not image_id:
|
|
|
- image_id = docker_build(dockerfile)
|
|
|
- params = ['sudo', 'docker', 'run',
|
|
|
- '--rm=true', '--interactive=true', '--tty=true',
|
|
|
- '--cap-drop=all', '--security-opt=no-new-privileges']
|
|
|
- params.extend(['--cap-add={}'.format(c) for c in caps])
|
|
|
- params.append(image_id)
|
|
|
- import shlex
|
|
|
- print(' '.join([shlex.quote(p) for p in params]))
|
|
|
- subprocess.run(params, check=True)
|
|
|
-
|
|
|
def locate(*patterns, match_all=True, ignore_case=True):
|
|
|
params = []
|
|
|
if match_all:
|
|
@@ -197,6 +198,9 @@ def os_read_non_blocking(fd, buffer_size_bytes=8*1024, timeout_seconds=0.1):
|
|
|
else:
|
|
|
return None
|
|
|
|
|
|
+def shlex_join(params):
|
|
|
+ return ' '.join(shlex.quote(p) for p in params)
|
|
|
+
|
|
|
def timestamp_now_utc():
|
|
|
return dt.datetime.utcnow().replace(tzinfo=dt.timezone.utc)
|
|
|
|
|
@@ -211,9 +215,8 @@ def timestamp_iso_local():
|
|
|
return timestamp_now_local().strftime('%Y%m%dT%H%M%S%z')
|
|
|
|
|
|
aliases['d'] = ['sudo', 'docker']
|
|
|
-aliases['d-r'] = lambda args: docker_run(**{
|
|
|
- 'dockerfile' if '\n' in args[0] else 'image_id': args[0],
|
|
|
-})
|
|
|
+aliases['d-r'] = ['d', 'run', '--rm=true',
|
|
|
+ '--cap-drop=all', '--security-opt=no-new-privileges']
|
|
|
aliases['dpkg-welse'] = lambda args: '\n'.join(dpkg_welse(args[0]))
|
|
|
aliases['dpkg-which'] = lambda args: '\t'.join(dpkg_which(args[0]))
|
|
|
aliases['g'] = ['git']
|