-
-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for using artifacts from another Job #185
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -771,8 +771,8 @@ Options available in `builder.yml`: | |
- `packages: bool` --- Component that generate packages (default: True). If set to False (e.g. `builder-rpm`), no `.qubesbuilder` file is allowed. | ||
- `verification-mode: str` --- component source code verification mode, supported values are: `signed-tag` (this is default), `less-secure-signed-commits-sufficient`, `insecure-skip-checking`. This option takes precedence over top level `less-secure-signed-commits-sufficient`. | ||
- `stages: List[Dict]` --- Allow to override stages options. | ||
- `distribution_name: List[Dict]` -- Allow to override per distribution, stages options. | ||
- `package_set: List[Dict]` -- Allow to override per distribution package set, stages options. | ||
- `distribution_name: List[Dict]` -- Allow to override per distribution, stages options or to provides dependencies. | ||
- `package_set: List[Dict]` -- Allow to override per distribution package set, stages options. | ||
|
||
- `templates: List[Dict]` -- List of templates you want to build. See example configs for sensible lists. | ||
- `<template_name>`: --- Template name. | ||
|
@@ -859,3 +859,34 @@ For the `fetch` stage, the Qubes executor with disposable template `qubes-builde | |
For the `build` stage of `vm-fc42`, the Podman executor with container image `fedoraimg` will be used. | ||
For the `sign` stage, the Qubes executor with disposable template `signing-access-dvm` will be used for both `vm-fc42` and `vm-jammy` | ||
For the `prep` stage of `vm-jammy`, the Local executor with base directory `/some/path` will be used. | ||
|
||
### Cross-compile Build | ||
|
||
To perform cross-compilation between distributions, you must declare dependencies using the `needs: List[Dict]` structure within the appropriate distribution stage. | ||
Each dependency is represented as a dictionary with the following keys: | ||
|
||
- `component: str` --- The name of the component. This value is not limited to the top-level component reference; it can reference any available component. | ||
- `distribution: str` --- The name of the target distribution. | ||
- `stage: str` --- The stage name for which the dependency is required. | ||
- `build: str` --- The build reference as provided in a `.qubesbuilder` file. | ||
|
||
For example: | ||
|
||
```yaml | ||
components: | ||
- installer-qubes-os: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. installer-qubes-os-windows-tools? (and below too) |
||
host-fc41: | ||
stages: | ||
- build: | ||
needs: | ||
- component: installer-qubes-os | ||
distribution: vm-win10 | ||
stage: build | ||
build: vs2022/installer.sln | ||
- component: installer-qubes-os | ||
distribution: vm-win10 | ||
stage: sign | ||
build: vs2022/installer.sln | ||
``` | ||
|
||
This example shows how to specify multiple dependencies for different stages (build and sign) under a given distribution. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,8 @@ | |
DistributionComponentPlugin, | ||
ComponentPlugin, | ||
TemplatePlugin, | ||
JobReference, | ||
JobDependency, | ||
) | ||
from qubesbuilder.template import QubesTemplate | ||
|
||
|
@@ -611,6 +613,56 @@ | |
def get_plugin_manager(self): | ||
return PluginManager(self.get_plugins_dirs()) | ||
|
||
def get_needs( | ||
self, | ||
component: QubesComponent, | ||
dist: QubesDistribution, | ||
stage_name: str, | ||
): | ||
needs = [] | ||
stages = component.kwargs.get(dist.distribution, {}).get("stages", []) | ||
for stage in stages: | ||
if ( | ||
isinstance(stage, dict) | ||
and next(iter(stage)) == stage_name | ||
and isinstance(stage[stage_name], dict) | ||
Comment on lines
+625
to
+628
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least some of this not matching should show a warning or even error. Otherwise it will be hard to find why it doesn't work if you make a typo (like extra |
||
): | ||
for need in stage[stage_name].get("needs", []): | ||
if all( | ||
[ | ||
need.get("component", None), | ||
need.get("distribution", None), | ||
need.get("stage", None), | ||
need.get("build", None), | ||
] | ||
Comment on lines
+631
to
+637
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and same here - if some part is missing, at least log a warning why it's ignored |
||
): | ||
filtered_components = self.get_components( | ||
[need["component"]] | ||
) | ||
if not filtered_components: | ||
raise ConfigError( | ||
f"Cannot find dependency component name '{need["component"]}'." | ||
) | ||
filtered_distributions = self.get_distributions( | ||
[need["distribution"]] | ||
) | ||
if not filtered_distributions: | ||
raise ConfigError( | ||
f"Cannot find dependency distribution name '{need["distribution"]}'." | ||
) | ||
needs.append( | ||
JobDependency( | ||
JobReference( | ||
component=filtered_components[0], | ||
dist=filtered_distributions[0], | ||
stage=need["stage"], | ||
template=None, | ||
build=need["build"], | ||
) | ||
) | ||
) | ||
return needs | ||
|
||
def get_jobs( | ||
self, | ||
components: List[QubesComponent], | ||
|
@@ -638,6 +690,11 @@ | |
) | ||
if not job: | ||
continue | ||
job.dependencies += self.get_needs( | ||
component=component, | ||
dist=distribution, | ||
stage_name=stage, | ||
) | ||
jobs.append(job) | ||
|
||
# ComponentPlugin | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -324,6 +324,16 @@ def default_copy_in(self, plugins_dir: Path, sources_dir: Path): | |
sources_dir, | ||
) | ||
) | ||
if dependency.builder_object == "job": | ||
artifact_path = get_artifact_path( | ||
self.config, dependency.reference | ||
) | ||
for artifact in artifact_path.parent.iterdir(): | ||
if artifact == artifact_path: | ||
continue | ||
copy_in.append( | ||
(artifact, self.executor.get_dependencies_dir()) | ||
) | ||
Comment on lines
+334
to
+336
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should they all be copied together, or maybe better in separate subdirs? what if file names conflict (for example you declare QWT use vm-win10 and vm-win11 if that would exist)? |
||
return copy_in | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, cross-compile is something else, like building ARM binaries on X86. Better use different term, like cross-distribution dependencies