Skip to content

Commit

Permalink
windows: remove qubesadmin dependency
Browse files Browse the repository at this point in the history
Signed-off-by: Rafał Wojdyła <[email protected]>
  • Loading branch information
omeg committed Feb 27, 2025
1 parent a23caaf commit d124a8a
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 223 deletions.
9 changes: 3 additions & 6 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,12 @@ builderv2-github:
PYTEST_ARGS: -v --color=yes --showlocals --cov qubesbuilder --cov-report term --cov-report html:artifacts/htmlcov --cov-report xml:artifacts/coverage.xml --junitxml=artifacts/qubesbuilder.xml
# https://gitlab.com/gitlab-org/gitlab/-/issues/15603
before_script:
- sudo dnf install -y python3-pip python3-pytest-cov python3-pytest python3-pytest-mock python3-lxml python3-wheel sequoia-sqv git
- sudo dnf install -y python3-pip python3-pytest-cov python3-pytest python3-pytest-mock python3-lxml python3-wheel sequoia-sqv
- sudo rm -rf ~/pytest-of-user/
- docker pull registry.gitlab.com/qubesos/docker-images/qubes-builder-fedora:latest
- docker tag registry.gitlab.com/qubesos/docker-images/qubes-builder-fedora:latest qubes-builder-fedora:latest
- mkdir ~/gitlab ~/tmp
- git clone https://github.com/QubesOS/qubes-core-admin-client ~/core-admin-client
- export PYTHONPATH=".:~/core-admin-client:$PYTHONPATH" BASE_ARTIFACTS_DIR=~/gitlab TMPDIR=~/tmp
- export PYTHONPATH=".:$PYTHONPATH" BASE_ARTIFACTS_DIR=~/gitlab TMPDIR=~/tmp
- env
after_script:
- ci/codecov-wrapper -f artifacts/coverage.xml
Expand Down Expand Up @@ -251,10 +250,8 @@ mypy:
tags:
- docker
before_script:
- sudo dnf install -y python3-mypy python3-pip git
- sudo dnf install -y python3-mypy python3-pip
- sudo python3 -m pip install types-PyYAML types-python-dateutil
- git clone https://github.com/QubesOS/qubes-core-admin-client ~/core-admin-client
- export PYTHONPATH="~/core-admin-client:$PYTHONPATH"
script:
- mypy --install-types --non-interactive --junit-xml mypy.xml qubesbuilder
artifacts:
Expand Down
133 changes: 133 additions & 0 deletions qubesbuilder/executors/qrexec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2021 Frédéric Pierret (fepitre) <[email protected]>
# Copyright (C) 2025 Rafał Wojdyła <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
import re
import subprocess
from typing import List, Optional

from qubesbuilder.common import sanitize_line
from qubesbuilder.executors import ExecutorError


def qrexec_call(
log,
what: str,
vm: str,
service: str,
args: Optional[List[str]] = None,
capture_output: bool = False,
options: Optional[List[str]] = None,
stdin: bytes = b"",
ignore_errors: bool = False,
) -> Optional[bytes]:
cmd = [
"/usr/lib/qubes/qrexec-client-vm",
]

if options:
cmd += options

cmd += [
"--",
vm,
service,
]

if args:
cmd += args

admin = service.startswith("admin.")
capture_output = capture_output or admin
try:
log.debug(f"qrexec call ({what}): {' '.join(cmd)}")
proc = subprocess.run(
cmd,
check=not ignore_errors,
capture_output=capture_output,
input=stdin,
)
except subprocess.CalledProcessError as e:
if e.stderr is not None:
content = sanitize_line(e.stderr.rstrip(b"\n")).rstrip()
else:
content = str(e)
msg = f"Failed to {what}: {content}"
raise ExecutorError(msg, name=vm)

if capture_output:
stdout = proc.stdout
if admin:
if not stdout.startswith(b"0\x00"):
stdout = stdout[2:].replace(b"\x00", b"\n")

if not ignore_errors:
raise ExecutorError(
f"Failed to {what}: qrexec call failed: {stdout.decode("ascii", "strict")}"
)
else:
log.debug(
f"Failed to {what}: qrexec call failed: {stdout.decode("ascii", "strict")}"
)
stdout = stdout[2:]
return stdout
return None


def create_dispvm(log, template: str) -> str:
stdout = qrexec_call(
log=log,
what="create disposable qube",
vm=template,
service="admin.vm.CreateDisposable",
)

assert stdout
if not re.match(rb"\Adisp(0|[1-9][0-9]{0,8})\Z", stdout):
raise ExecutorError("Failed to create disposable qube.")
try:
return stdout.decode("ascii", "strict")
except UnicodeDecodeError as e:
raise ExecutorError(f"Failed to obtain disposable qube name: {str(e)}")


def start_vm(log, vm: str):
qrexec_call(
log=log,
what="start vm",
vm=vm,
service="admin.vm.Start",
)


def kill_vm(log, vm: str):
qrexec_call(
log=log,
what="kill vm",
vm=vm,
service="admin.vm.Kill",
ignore_errors=True,
)

qrexec_call(
log=log,
what="remove vm",
vm=vm,
service="admin.vm.Remove",
ignore_errors=True,
)
Loading

0 comments on commit d124a8a

Please sign in to comment.