mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-27 10:44:33 +00:00
*: Always pass check= argument to subprocess.run()
- Avoid flake8 warnings. - Makes the call more explicitly readable in case an exception is expected but check=True is not passed by mistake. Tests: - Many tests are skipped since the changes are considered trivial. check=False is already the default for subprocess.run() method. - actions/package: Install an app when it is not installed. - actions/upgrade: Run manual upgrades. - actions/users: Change a user password. Login. Create/remove a user. - actions/zoph: Restore a database. - container: On a fresh repository, run ./container up,ssh,stop,destroy for a testing container. - plinth/action_utils.py: Enable/disable an app that has a running service. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
ebd357476d
commit
9bd1f80d5c
@ -226,7 +226,8 @@ def _get_ssh_key_file_for_import(original_key_file, service):
|
|||||||
shutil.copy2(original_key_file, key_file)
|
shutil.copy2(original_key_file, key_file)
|
||||||
# Convert OpenSSH format to PEM
|
# Convert OpenSSH format to PEM
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
['ssh-keygen', '-p', '-N', '', '-m', 'PEM', '-f', key_file])
|
['ssh-keygen', '-p', '-N', '', '-m', 'PEM', '-f', key_file],
|
||||||
|
check=True)
|
||||||
yield key_file
|
yield key_file
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -96,7 +96,7 @@ def subcommand_install(arguments):
|
|||||||
if arguments.force_missing_configuration:
|
if arguments.force_missing_configuration:
|
||||||
extra_arguments += ['-o', 'Dpkg::Options::=--force-confmiss']
|
extra_arguments += ['-o', 'Dpkg::Options::=--force-confmiss']
|
||||||
|
|
||||||
subprocess.run(['dpkg', '--configure', '-a'])
|
subprocess.run(['dpkg', '--configure', '-a'], check=False)
|
||||||
with apt_hold_freedombox():
|
with apt_hold_freedombox():
|
||||||
run_apt_command(['--fix-broken', 'install'])
|
run_apt_command(['--fix-broken', 'install'])
|
||||||
returncode = run_apt_command(['install'] + extra_arguments +
|
returncode = run_apt_command(['install'] + extra_arguments +
|
||||||
|
|||||||
@ -273,7 +273,7 @@ def subcommand_mount(arguments):
|
|||||||
process = subprocess.run([
|
process = subprocess.run([
|
||||||
'udisksctl', 'mount', '--block-device', arguments.block_device,
|
'udisksctl', 'mount', '--block-device', arguments.block_device,
|
||||||
'--no-user-interaction'
|
'--no-user-interaction'
|
||||||
])
|
], check=False)
|
||||||
sys.exit(process.returncode)
|
sys.exit(process.returncode)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -140,7 +140,7 @@ def parse_arguments():
|
|||||||
|
|
||||||
def _run():
|
def _run():
|
||||||
"""Run unattended-upgrades"""
|
"""Run unattended-upgrades"""
|
||||||
subprocess.run(['dpkg', '--configure', '-a'])
|
subprocess.run(['dpkg', '--configure', '-a'], check=False)
|
||||||
run_apt_command(['--fix-broken', 'install'])
|
run_apt_command(['--fix-broken', 'install'])
|
||||||
|
|
||||||
# In case freedombox package was left in held state by an
|
# In case freedombox package was left in held state by an
|
||||||
@ -453,7 +453,7 @@ def _perform_dist_upgrade():
|
|||||||
['grub-pc grub-pc/install_devices_empty boolean true'])
|
['grub-pc grub-pc/install_devices_empty boolean true'])
|
||||||
|
|
||||||
print('Running unattended-upgrade...', flush=True)
|
print('Running unattended-upgrade...', flush=True)
|
||||||
subprocess.run(['unattended-upgrade', '--verbose'])
|
subprocess.run(['unattended-upgrade', '--verbose'], check=False)
|
||||||
|
|
||||||
# Remove obsolete packages that may prevent other packages from
|
# Remove obsolete packages that may prevent other packages from
|
||||||
# upgrading.
|
# upgrading.
|
||||||
@ -492,7 +492,7 @@ def _perform_dist_upgrade():
|
|||||||
# Run unattended-upgrade once more to handle upgrading the
|
# Run unattended-upgrade once more to handle upgrading the
|
||||||
# freedombox package.
|
# freedombox package.
|
||||||
print('Running unattended-upgrade...', flush=True)
|
print('Running unattended-upgrade...', flush=True)
|
||||||
subprocess.run(['unattended-upgrade', '--verbose'])
|
subprocess.run(['unattended-upgrade', '--verbose'], check=False)
|
||||||
|
|
||||||
# Restore original snapshots configuration.
|
# Restore original snapshots configuration.
|
||||||
if snapshots_supported and apt_snapshots_enabled:
|
if snapshots_supported and apt_snapshots_enabled:
|
||||||
|
|||||||
@ -373,7 +373,7 @@ def set_samba_user(username, password):
|
|||||||
"""
|
"""
|
||||||
proc = subprocess.run(['smbpasswd', '-a', '-s', username],
|
proc = subprocess.run(['smbpasswd', '-a', '-s', username],
|
||||||
input='{0}\n{0}\n'.format(password).encode(),
|
input='{0}\n{0}\n'.format(password).encode(),
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE, check=False)
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
raise RuntimeError('Unable to add Samba user: ', proc.stderr)
|
raise RuntimeError('Unable to add Samba user: ', proc.stderr)
|
||||||
|
|
||||||
@ -580,13 +580,12 @@ def flush_cache():
|
|||||||
action_utils.service_reload('apache2')
|
action_utils.service_reload('apache2')
|
||||||
|
|
||||||
|
|
||||||
def _run(arguments, **kwargs):
|
def _run(arguments, check=True, **kwargs):
|
||||||
"""Run a command. Check return code and suppress output by default."""
|
"""Run a command. Check return code and suppress output by default."""
|
||||||
env = dict(os.environ, LDAPSCRIPTS_CONF=LDAPSCRIPTS_CONF)
|
env = dict(os.environ, LDAPSCRIPTS_CONF=LDAPSCRIPTS_CONF)
|
||||||
kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL)
|
kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL)
|
||||||
kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL)
|
kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL)
|
||||||
kwargs['check'] = kwargs.get('check', True)
|
return subprocess.run(arguments, env=env, check=check, **kwargs)
|
||||||
return subprocess.run(arguments, env=env, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
@ -128,7 +128,7 @@ def subcommand_dump_database(_):
|
|||||||
def subcommand_restore_database(_):
|
def subcommand_restore_database(_):
|
||||||
"""Restore database from file."""
|
"""Restore database from file."""
|
||||||
db_name = _get_db_name()
|
db_name = _get_db_name()
|
||||||
subprocess.run(['mysqladmin', '--force', 'drop', db_name])
|
subprocess.run(['mysqladmin', '--force', 'drop', db_name], check=False)
|
||||||
subprocess.run(['mysqladmin', 'create', db_name], check=True)
|
subprocess.run(['mysqladmin', 'create', db_name], check=True)
|
||||||
with open(DB_BACKUP_FILE, 'r') as db_restore_file:
|
with open(DB_BACKUP_FILE, 'r') as db_restore_file:
|
||||||
subprocess.run(['mysql', db_name], stdin=db_restore_file, check=True)
|
subprocess.run(['mysql', db_name], stdin=db_restore_file, check=True)
|
||||||
|
|||||||
46
container
46
container
@ -327,7 +327,7 @@ def _check_command(command):
|
|||||||
else:
|
else:
|
||||||
which = ['sudo', 'which', command]
|
which = ['sudo', 'which', command]
|
||||||
|
|
||||||
process = subprocess.run(which, stdout=subprocess.DEVNULL)
|
process = subprocess.run(which, stdout=subprocess.DEVNULL, check=False)
|
||||||
return process.returncode == 0
|
return process.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
@ -341,7 +341,8 @@ def _verify_dependencies():
|
|||||||
# it leading to machinectl start failing first time after boot. See
|
# it leading to machinectl start failing first time after boot. See
|
||||||
# https://github.com/systemd/systemd/issues/13130 . Workaround for old
|
# https://github.com/systemd/systemd/issues/13130 . Workaround for old
|
||||||
# versions of machinectl. Ignore errors.
|
# versions of machinectl. Ignore errors.
|
||||||
subprocess.run(['sudo', 'modprobe', '--all', '--quiet', 'loop'])
|
subprocess.run(['sudo', 'modprobe', '--all', '--quiet', 'loop'],
|
||||||
|
check=False)
|
||||||
|
|
||||||
dependencies = {
|
dependencies = {
|
||||||
'systemd-nspawn': 'systemd-container',
|
'systemd-nspawn': 'systemd-container',
|
||||||
@ -370,13 +371,13 @@ def _verify_dependencies():
|
|||||||
' '.join(missing_commands))
|
' '.join(missing_commands))
|
||||||
|
|
||||||
process = subprocess.run(['lsb_release', '--id', '--short'],
|
process = subprocess.run(['lsb_release', '--id', '--short'],
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE, check=False)
|
||||||
if process.stdout.decode().strip() != 'Debian':
|
if process.stdout.decode().strip() != 'Debian':
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
logger.info('Running apt for missing packages: %s',
|
logger.info('Running apt for missing packages: %s',
|
||||||
' '.join(missing_commands))
|
' '.join(missing_commands))
|
||||||
subprocess.run(['sudo', 'apt', 'install'] + missing_packages)
|
subprocess.run(['sudo', 'apt', 'install'] + missing_packages, check=False)
|
||||||
|
|
||||||
|
|
||||||
def _get_systemd_nspawn_version():
|
def _get_systemd_nspawn_version():
|
||||||
@ -583,7 +584,7 @@ def _setup_nm_connection(distribution):
|
|||||||
connection_name = f'fbx-{distribution}-shared'
|
connection_name = f'fbx-{distribution}-shared'
|
||||||
process = subprocess.run(
|
process = subprocess.run(
|
||||||
['sudo', 'nmcli', 'connection', 'show', connection_name],
|
['sudo', 'nmcli', 'connection', 'show', connection_name],
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
|
||||||
if not process.returncode:
|
if not process.returncode:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -600,7 +601,8 @@ def _setup_nm_connection(distribution):
|
|||||||
subprocess.run(['sudo', 'nmcli', 'connection', 'add'] +
|
subprocess.run(['sudo', 'nmcli', 'connection', 'add'] +
|
||||||
list(itertools.chain(*properties.items())), check=True)
|
list(itertools.chain(*properties.items())), check=True)
|
||||||
subprocess.run(['sudo', 'nmcli', 'connection', 'up', connection_name],
|
subprocess.run(['sudo', 'nmcli', 'connection', 'up', connection_name],
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||||
|
check=False)
|
||||||
|
|
||||||
|
|
||||||
def _setup_users(image_file):
|
def _setup_users(image_file):
|
||||||
@ -649,7 +651,7 @@ def _setup_ssh(image_file):
|
|||||||
logger.info('Generating SSH client key %s', key_file)
|
logger.info('Generating SSH client key %s', key_file)
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
['ssh-keygen', '-t', 'ed25519', '-N', '', '-f',
|
['ssh-keygen', '-t', 'ed25519', '-N', '', '-f',
|
||||||
str(key_file)], stdout=subprocess.DEVNULL)
|
str(key_file)], stdout=subprocess.DEVNULL, check=True)
|
||||||
|
|
||||||
public_key_file = key_file.with_suffix('.pub')
|
public_key_file = key_file.with_suffix('.pub')
|
||||||
public_key = public_key_file.read_bytes()
|
public_key = public_key_file.read_bytes()
|
||||||
@ -713,33 +715,35 @@ VirtualEthernet=yes
|
|||||||
'''
|
'''
|
||||||
nspawn_file = f'/run/systemd/nspawn/{machine_name}.nspawn'
|
nspawn_file = f'/run/systemd/nspawn/{machine_name}.nspawn'
|
||||||
logger.info('Creating systemd-nspawn configuration: %s', nspawn_file)
|
logger.info('Creating systemd-nspawn configuration: %s', nspawn_file)
|
||||||
subprocess.run(['sudo', 'rm', '--force', nspawn_file])
|
subprocess.run(['sudo', 'rm', '--force', nspawn_file], check=False)
|
||||||
subprocess.run(['sudo', 'tee', nspawn_file], input=nspawn_options.encode(),
|
subprocess.run(['sudo', 'tee', nspawn_file], input=nspawn_options.encode(),
|
||||||
stdout=subprocess.DEVNULL, check=True)
|
stdout=subprocess.DEVNULL, check=True)
|
||||||
|
|
||||||
image_link = pathlib.Path(f'/var/lib/machines/{machine_name}.raw')
|
image_link = pathlib.Path(f'/var/lib/machines/{machine_name}.raw')
|
||||||
logger.info('Linking systemd-nspawn image %s -> %s', image_link,
|
logger.info('Linking systemd-nspawn image %s -> %s', image_link,
|
||||||
image_file)
|
image_file)
|
||||||
result = subprocess.run(['sudo', 'test', '-e', str(image_link)])
|
result = subprocess.run(
|
||||||
|
['sudo', 'test', '-e', str(image_link)], check=False)
|
||||||
if not result.returncode:
|
if not result.returncode:
|
||||||
result = subprocess.run(['sudo', 'test', '-L', str(image_link)])
|
result = subprocess.run(
|
||||||
|
['sudo', 'test', '-L', str(image_link)], check=False)
|
||||||
if result.returncode:
|
if result.returncode:
|
||||||
raise Exception(f'Image file {image_link} is not a symlink.')
|
raise Exception(f'Image file {image_link} is not a symlink.')
|
||||||
|
|
||||||
subprocess.run(['sudo', 'rm', '--force', str(image_link)])
|
subprocess.run(['sudo', 'rm', '--force', str(image_link)], check=False)
|
||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'sudo', 'ln', '--symbolic',
|
'sudo', 'ln', '--symbolic',
|
||||||
str(image_file.resolve()),
|
str(image_file.resolve()),
|
||||||
str(image_link)
|
str(image_link)
|
||||||
])
|
], check=False)
|
||||||
|
|
||||||
|
|
||||||
def _get_machine_status(machine_name):
|
def _get_machine_status(machine_name):
|
||||||
"""Return the running status of a container."""
|
"""Return the running status of a container."""
|
||||||
process = subprocess.run(['sudo', 'machinectl', 'status', machine_name],
|
process = subprocess.run(['sudo', 'machinectl', 'status', machine_name],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL)
|
stderr=subprocess.DEVNULL, check=False)
|
||||||
return process.returncode == 0
|
return process.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
@ -756,14 +760,14 @@ def _launch(image_file, distribution):
|
|||||||
f'fbx-{distribution}-shared')
|
f'fbx-{distribution}-shared')
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
['sudo', 'nmcli', 'connection', 'up', f'fbx-{distribution}-shared'],
|
['sudo', 'nmcli', 'connection', 'up', f'fbx-{distribution}-shared'],
|
||||||
stdout=subprocess.DEVNULL)
|
stdout=subprocess.DEVNULL, check=False)
|
||||||
|
|
||||||
|
|
||||||
def _stop(distribution):
|
def _stop(distribution):
|
||||||
"""Stop the container."""
|
"""Stop the container."""
|
||||||
machine_name = f'fbx-{distribution}'
|
machine_name = f'fbx-{distribution}'
|
||||||
logger.info('Running `machinectl stop %s`', machine_name)
|
logger.info('Running `machinectl stop %s`', machine_name)
|
||||||
subprocess.run(['sudo', 'machinectl', 'stop', machine_name])
|
subprocess.run(['sudo', 'machinectl', 'stop', machine_name], check=False)
|
||||||
_wait_for(lambda: not _get_machine_status(machine_name))
|
_wait_for(lambda: not _get_machine_status(machine_name))
|
||||||
|
|
||||||
|
|
||||||
@ -771,7 +775,8 @@ def _terminate(distribution):
|
|||||||
"""Terminal the container."""
|
"""Terminal the container."""
|
||||||
machine_name = f'fbx-{distribution}'
|
machine_name = f'fbx-{distribution}'
|
||||||
logger.info('Running `machinectl terminate %s`', machine_name)
|
logger.info('Running `machinectl terminate %s`', machine_name)
|
||||||
subprocess.run(['sudo', 'machinectl', 'terminate', machine_name])
|
subprocess.run(['sudo', 'machinectl', 'terminate', machine_name],
|
||||||
|
check=False)
|
||||||
_wait_for(lambda: not _get_machine_status(machine_name))
|
_wait_for(lambda: not _get_machine_status(machine_name))
|
||||||
|
|
||||||
|
|
||||||
@ -781,16 +786,17 @@ def _destroy(distribution):
|
|||||||
image_link = pathlib.Path(f'/var/lib/machines/{machine_name}.raw')
|
image_link = pathlib.Path(f'/var/lib/machines/{machine_name}.raw')
|
||||||
|
|
||||||
logger.info('Removing link to systemd-nspawn image %s', image_link)
|
logger.info('Removing link to systemd-nspawn image %s', image_link)
|
||||||
subprocess.run(['sudo', 'rm', '--force', str(image_link)])
|
subprocess.run(['sudo', 'rm', '--force', str(image_link)], check=False)
|
||||||
nspawn_file = f'/run/systemd/nspawn/{machine_name}.nspawn'
|
nspawn_file = f'/run/systemd/nspawn/{machine_name}.nspawn'
|
||||||
|
|
||||||
logger.info('Removing systemd-nspawn configuration: %s', nspawn_file)
|
logger.info('Removing systemd-nspawn configuration: %s', nspawn_file)
|
||||||
subprocess.run(['sudo', 'rm', '--force', nspawn_file])
|
subprocess.run(['sudo', 'rm', '--force', nspawn_file], check=False)
|
||||||
|
|
||||||
overlay_folder = _get_overlay_folder(distribution)
|
overlay_folder = _get_overlay_folder(distribution)
|
||||||
logger.info('Removing overlay folder with container written data: %s',
|
logger.info('Removing overlay folder with container written data: %s',
|
||||||
overlay_folder)
|
overlay_folder)
|
||||||
subprocess.run(['sudo', 'rm', '-r', '--force', overlay_folder])
|
subprocess.run(['sudo', 'rm', '-r', '--force', overlay_folder],
|
||||||
|
check=False)
|
||||||
|
|
||||||
compressed_image = _get_compressed_image_path(distribution)
|
compressed_image = _get_compressed_image_path(distribution)
|
||||||
image_file = compressed_image.with_suffix('')
|
image_file = compressed_image.with_suffix('')
|
||||||
@ -814,7 +820,7 @@ def _destroy(distribution):
|
|||||||
logger.info('Removing Network Manager connection %s', connection_name)
|
logger.info('Removing Network Manager connection %s', connection_name)
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
['sudo', 'nmcli', 'connection', 'delete', connection_name],
|
['sudo', 'nmcli', 'connection', 'delete', connection_name],
|
||||||
capture_output=True)
|
capture_output=True, check=False)
|
||||||
if result.returncode not in (0, 10):
|
if result.returncode not in (0, 10):
|
||||||
# nmcli failed and not due to 'Connection, device, or access point does
|
# nmcli failed and not due to 'Connection, device, or access point does
|
||||||
# not exist.' See
|
# not exist.' See
|
||||||
|
|||||||
@ -128,10 +128,10 @@ def service_action(service_name, action):
|
|||||||
"""Perform the given action on the service_name."""
|
"""Perform the given action on the service_name."""
|
||||||
if is_systemd_running():
|
if is_systemd_running():
|
||||||
subprocess.run(['systemctl', action, service_name],
|
subprocess.run(['systemctl', action, service_name],
|
||||||
stdout=subprocess.DEVNULL)
|
stdout=subprocess.DEVNULL, check=False)
|
||||||
else:
|
else:
|
||||||
subprocess.run(['service', service_name, action],
|
subprocess.run(['service', service_name, action],
|
||||||
stdout=subprocess.DEVNULL)
|
stdout=subprocess.DEVNULL, check=False)
|
||||||
|
|
||||||
|
|
||||||
def webserver_is_enabled(name, kind='config'):
|
def webserver_is_enabled(name, kind='config'):
|
||||||
@ -371,7 +371,7 @@ Owners: {package}
|
|||||||
env['DEBCONF_DB_OVERRIDE'] = 'File{' + override_file.name + \
|
env['DEBCONF_DB_OVERRIDE'] = 'File{' + override_file.name + \
|
||||||
' readonly:true}'
|
' readonly:true}'
|
||||||
env['DEBIAN_FRONTEND'] = 'noninteractive'
|
env['DEBIAN_FRONTEND'] = 'noninteractive'
|
||||||
subprocess.run(['dpkg-reconfigure', package], env=env)
|
subprocess.run(['dpkg-reconfigure', package], env=env, check=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.remove(override_file.name)
|
os.remove(override_file.name)
|
||||||
@ -419,7 +419,7 @@ def run_apt_command(arguments):
|
|||||||
env['DEBIAN_FRONTEND'] = 'noninteractive'
|
env['DEBIAN_FRONTEND'] = 'noninteractive'
|
||||||
process = subprocess.run(command, stdin=subprocess.DEVNULL,
|
process = subprocess.run(command, stdin=subprocess.DEVNULL,
|
||||||
stdout=subprocess.DEVNULL, close_fds=False,
|
stdout=subprocess.DEVNULL, close_fds=False,
|
||||||
env=env)
|
env=env, check=False)
|
||||||
return process.returncode
|
return process.returncode
|
||||||
|
|
||||||
|
|
||||||
@ -458,7 +458,8 @@ def apt_hold_freedombox():
|
|||||||
def apt_unhold_freedombox():
|
def apt_unhold_freedombox():
|
||||||
"""Remove any hold on freedombox package, and clear flag."""
|
"""Remove any hold on freedombox package, and clear flag."""
|
||||||
subprocess.run(['apt-mark', 'unhold', 'freedombox'],
|
subprocess.run(['apt-mark', 'unhold', 'freedombox'],
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||||
|
check=False)
|
||||||
if apt_hold_flag.exists():
|
if apt_hold_flag.exists():
|
||||||
apt_hold_flag.unlink()
|
apt_hold_flag.unlink()
|
||||||
|
|
||||||
|
|||||||
@ -285,12 +285,13 @@ class VerifySshHostkeyForm(forms.Form):
|
|||||||
# Fetch public keys of ssh remote
|
# Fetch public keys of ssh remote
|
||||||
keyscan = subprocess.run(['ssh-keyscan', hostname],
|
keyscan = subprocess.run(['ssh-keyscan', hostname],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE, check=False)
|
||||||
keys = keyscan.stdout.decode().splitlines()
|
keys = keyscan.stdout.decode().splitlines()
|
||||||
error_message = keyscan.stderr.decode() if keyscan.returncode else None
|
error_message = keyscan.stderr.decode() if keyscan.returncode else None
|
||||||
# Generate user-friendly fingerprints of public keys
|
# Generate user-friendly fingerprints of public keys
|
||||||
keygen = subprocess.run(['ssh-keygen', '-l', '-f', '-'],
|
keygen = subprocess.run(['ssh-keygen', '-l', '-f', '-'],
|
||||||
input=keyscan.stdout, stdout=subprocess.PIPE)
|
input=keyscan.stdout, stdout=subprocess.PIPE,
|
||||||
|
check=False)
|
||||||
fingerprints = keygen.stdout.decode().splitlines()
|
fingerprints = keygen.stdout.decode().splitlines()
|
||||||
|
|
||||||
return zip(keys, fingerprints), error_message
|
return zip(keys, fingerprints), error_message
|
||||||
|
|||||||
@ -38,7 +38,7 @@ def fixture_password():
|
|||||||
|
|
||||||
def get_hashed_password(password):
|
def get_hashed_password(password):
|
||||||
res = subprocess.run(['mkpasswd', '--method=md5', password],
|
res = subprocess.run(['mkpasswd', '--method=md5', password],
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE, check=True)
|
||||||
return res.stdout.decode().strip()
|
return res.stdout.decode().strip()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -244,8 +244,8 @@ def _action_set_keys():
|
|||||||
clean_dict[key] = clean_function(value)
|
clean_dict[key] = clean_function(value)
|
||||||
|
|
||||||
# Apply changes (postconf)
|
# Apply changes (postconf)
|
||||||
postconf_dict = dict(filter(lambda kv: not kv[0].startswith('_'),
|
postconf_dict = dict(
|
||||||
clean_dict.items()))
|
filter(lambda kv: not kv[0].startswith('_'), clean_dict.items()))
|
||||||
postconf.set_many(postconf_dict)
|
postconf.set_many(postconf_dict)
|
||||||
|
|
||||||
# Apply changes (special)
|
# Apply changes (special)
|
||||||
@ -258,7 +258,7 @@ def _action_set_keys():
|
|||||||
with postconf.mutex.lock_all():
|
with postconf.mutex.lock_all():
|
||||||
# systemctl reload postfix
|
# systemctl reload postfix
|
||||||
args = ['systemctl', 'reload', 'postfix']
|
args = ['systemctl', 'reload', 'postfix']
|
||||||
completed = subprocess.run(args, capture_output=True)
|
completed = subprocess.run(args, capture_output=True, check=False)
|
||||||
if completed.returncode != 0:
|
if completed.returncode != 0:
|
||||||
interproc.log_subprocess(completed)
|
interproc.log_subprocess(completed)
|
||||||
raise OSError('Could not reload postfix')
|
raise OSError('Could not reload postfix')
|
||||||
|
|||||||
@ -65,7 +65,7 @@ def action_mk(arg_type, user_info):
|
|||||||
|
|
||||||
args = ['sudo', '-n', '--user=#' + str(passwd.pw_uid)]
|
args = ['sudo', '-n', '--user=#' + str(passwd.pw_uid)]
|
||||||
args.extend(['/bin/sh', '-c', 'mkdir -p ~'])
|
args.extend(['/bin/sh', '-c', 'mkdir -p ~'])
|
||||||
completed = subprocess.run(args, capture_output=True)
|
completed = subprocess.run(args, capture_output=True, check=False)
|
||||||
if completed.returncode != 0:
|
if completed.returncode != 0:
|
||||||
interproc.log_subprocess(completed)
|
interproc.log_subprocess(completed)
|
||||||
raise OSError('Could not create home directory')
|
raise OSError('Could not create home directory')
|
||||||
|
|||||||
@ -140,7 +140,7 @@ def _compile_sieve():
|
|||||||
def _run_sievec(sieve_file):
|
def _run_sievec(sieve_file):
|
||||||
logger.info('Compiling sieve script %s', sieve_file)
|
logger.info('Compiling sieve script %s', sieve_file)
|
||||||
args = ['sievec', '--', sieve_file]
|
args = ['sievec', '--', sieve_file]
|
||||||
completed = subprocess.run(args, capture_output=True)
|
completed = subprocess.run(args, capture_output=True, check=False)
|
||||||
if completed.returncode != 0:
|
if completed.returncode != 0:
|
||||||
interproc.log_subprocess(completed)
|
interproc.log_subprocess(completed)
|
||||||
raise OSError('Sieve compilation failed: ' + sieve_file)
|
raise OSError('Sieve compilation failed: ' + sieve_file)
|
||||||
|
|||||||
@ -89,7 +89,7 @@ class Mutex:
|
|||||||
args.extend(['/bin/sh', '-c'])
|
args.extend(['/bin/sh', '-c'])
|
||||||
args.append('umask 177 && > ' + self.lock_path)
|
args.append('umask 177 && > ' + self.lock_path)
|
||||||
|
|
||||||
completed = subprocess.run(args, capture_output=True)
|
completed = subprocess.run(args, capture_output=True, check=False)
|
||||||
if completed.returncode != 0:
|
if completed.returncode != 0:
|
||||||
interproc.log_subprocess(completed)
|
interproc.log_subprocess(completed)
|
||||||
raise OSError('Could not create ' + self.lock_path)
|
raise OSError('Could not create ' + self.lock_path)
|
||||||
|
|||||||
@ -56,7 +56,7 @@ class Disk():
|
|||||||
command = 'losetup --show --find {file}'.format(
|
command = 'losetup --show --find {file}'.format(
|
||||||
file=self.disk_file.name)
|
file=self.disk_file.name)
|
||||||
process = subprocess.run(command.split(), stdout=subprocess.PIPE,
|
process = subprocess.run(command.split(), stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE, check=False)
|
||||||
if process.returncode:
|
if process.returncode:
|
||||||
if b'cannot find an unused loop device' in process.stderr:
|
if b'cannot find an unused loop device' in process.stderr:
|
||||||
pytest.skip('Loopback devices not available')
|
pytest.skip('Loopback devices not available')
|
||||||
@ -107,7 +107,7 @@ class Disk():
|
|||||||
|
|
||||||
def _cleanup_loopback(self):
|
def _cleanup_loopback(self):
|
||||||
"""Undo the loopback device setup."""
|
"""Undo the loopback device setup."""
|
||||||
subprocess.run(['losetup', '--detach', self.device])
|
subprocess.run(['losetup', '--detach', self.device], check=False)
|
||||||
|
|
||||||
def _remove_disk_file(self):
|
def _remove_disk_file(self):
|
||||||
"""Delete the disk_file."""
|
"""Delete the disk_file."""
|
||||||
@ -231,16 +231,15 @@ class TestActions:
|
|||||||
self.assert_aligned(partition_number)
|
self.assert_aligned(partition_number)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def call_action(action_command, **kwargs):
|
def call_action(action_command, check=True, **kwargs):
|
||||||
"""Call the action script."""
|
"""Call the action script."""
|
||||||
test_directory = pathlib.Path(__file__).parent
|
test_directory = pathlib.Path(__file__).parent
|
||||||
top_directory = (test_directory / '..' / '..' / '..' / '..').resolve()
|
top_directory = (test_directory / '..' / '..' / '..' / '..').resolve()
|
||||||
action_command[0] = top_directory / 'actions' / action_command[0]
|
action_command[0] = top_directory / 'actions' / action_command[0]
|
||||||
kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL)
|
kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL)
|
||||||
kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL)
|
kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL)
|
||||||
kwargs['check'] = kwargs.get('check', True)
|
|
||||||
env = dict(os.environ, PYTHONPATH=str(top_directory))
|
env = dict(os.environ, PYTHONPATH=str(top_directory))
|
||||||
return subprocess.run(action_command, env=env, **kwargs)
|
return subprocess.run(action_command, env=env, check=check, **kwargs)
|
||||||
|
|
||||||
def check_action(self, action_command):
|
def check_action(self, action_command):
|
||||||
"""Return success/failure result of the action command."""
|
"""Return success/failure result of the action command."""
|
||||||
@ -255,7 +254,7 @@ class TestActions:
|
|||||||
subprocess.run([
|
subprocess.run([
|
||||||
'parted', '--script', self.device, 'align-check', 'opti',
|
'parted', '--script', self.device, 'align-check', 'opti',
|
||||||
str(partition_number)
|
str(partition_number)
|
||||||
])
|
], check=True)
|
||||||
|
|
||||||
def assert_btrfs_file_system_healthy(self, partition_number):
|
def assert_btrfs_file_system_healthy(self, partition_number):
|
||||||
"""Perform a successful ext4 file system check."""
|
"""Perform a successful ext4 file system check."""
|
||||||
|
|||||||
@ -114,7 +114,8 @@ def get_log():
|
|||||||
def _is_updating():
|
def _is_updating():
|
||||||
"""Check if manually triggered update is running."""
|
"""Check if manually triggered update is running."""
|
||||||
command = ['systemctl', 'is-active', 'freedombox-manual-upgrade']
|
command = ['systemctl', 'is-active', 'freedombox-manual-upgrade']
|
||||||
result = subprocess.run(command, capture_output=True, text=True)
|
result = subprocess.run(command, capture_output=True, text=True,
|
||||||
|
check=False)
|
||||||
return str(result.stdout).startswith('activ') # 'active' or 'activating'
|
return str(result.stdout).startswith('activ') # 'active' or 'activating'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -138,12 +138,11 @@ def fixture_auto_cleanup_users_groups(needs_root, load_cfg):
|
|||||||
_delete_group(group)
|
_delete_group(group)
|
||||||
|
|
||||||
|
|
||||||
def _call_action(arguments, **kwargs):
|
def _call_action(arguments, check=True, **kwargs):
|
||||||
"""Call the action script."""
|
"""Call the action script."""
|
||||||
kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE)
|
kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE)
|
||||||
kwargs['stderr'] = kwargs.get('stderr', subprocess.PIPE)
|
kwargs['stderr'] = kwargs.get('stderr', subprocess.PIPE)
|
||||||
kwargs['check'] = kwargs.get('check', True)
|
return subprocess.run([_action_file()] + arguments, check=check, **kwargs)
|
||||||
return subprocess.run([_action_file()] + arguments, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def _create_user(username=None, groups=None):
|
def _create_user(username=None, groups=None):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user