Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions firestarter/cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,43 @@ def main():
arg_parser = argparse.ArgumentParser()

arg_parser.add_argument('workflow', type=str, help='Name of the workflow to run')
arg_parser.add_argument('--vars', type=str, help='Variables to pass to the workflow, in inline table toml format. Example: --vars=\'vars = { var1= "value1", var2= "value2"}\'')
arg_parser.add_argument('--secrets', type=str, help='Secrets to pass to the workflow, in inline table toml format. Example: --secrets=\'secrets = { secret1= "foo", secret2= "bar"}\'')
arg_parser.add_argument('--vars', type=str, help='Variables to pass to the workflow, as an inline toml format dict. Example: --vars=\'{ var1= "value1", var2= "value2"}\'')
arg_parser.add_argument('--secrets', type=str, help='Secrets to pass to the workflow, as an inline toml format dict. Example: --secrets=\'{ secret1= "foo", secret2= "bar"}\'')
arg_parser.add_argument('--additional_build_args', type=str, help='Additional build_args to pass to the workflow, as an inline toml format dict. Example: --additional_build_args=\'{ build_arg1= "arg1", build_arg2= "arg2"}\'')
arg_parser.add_argument('--config_file', type=str, help='Optional configuration file for the workflow, located in the repository')
args = arg_parser.parse_args()

input_vars = os.environ.get("INPUT_VARS", None)
input_secrets = os.environ.get("INPUT_SECRETS", None)
input_additional_build_args = os.environ.get("INPUT_ADDITIONAL_BUILD_ARGS", None)
input_config_file = os.environ.get("INPUT_CONFIG_FILE", None)

vars = tomllib.loads(input_vars) if input_vars is not None else {}
secrets = tomllib.loads(input_secrets) if input_secrets is not None else {}
additional_build_args =\
tomllib.loads(input_additional_build_args) if input_additional_build_args is not None else {}
config_file = input_config_file if input_config_file is not None else args.config_file

if args.vars:
args.vars = f"vars = {args.vars}"
vars.update(tomllib.loads(args.vars).get("vars"))
logger.debug(f"Inline vars: {vars}")
if args.secrets:
args.secrets = f"secrets = {args.secrets}"
secrets.update(tomllib.loads(args.secrets).get("secrets"))
logger.debug(f"Inline secrets: {secrets}")
if args.additional_build_args:
args.additional_build_args = f"additional_build_args = {args.additional_build_args}"
additional_build_args.update(tomllib.loads(args.additional_build_args).get("additional_build_args"))
logger.debug(f"Inline additional_build_args: {additional_build_args}")

# Import the workflow module from the workflow name
workflow = importlib.import_module(f"firestarter.workflows.{args.workflow}")
logger.info(f"Running workflow {args.workflow} with vars {vars} and secrets {secrets}")
result = workflow.run(
vars=vars,
secrets=secrets,
additional_build_args=additional_build_args,
config_file=config_file,
)

Expand Down
5 changes: 5 additions & 0 deletions firestarter/common/firestarter_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ def __init__(self, **kwargs) -> None:
self._config_file = kwargs.get('config_file', None)
self._vars = kwargs.get('vars', None)
self._secrets = kwargs.get('secrets', None)
self._additional_build_args = kwargs.get('additional_build_args', None)
self.__validate_required_vars()

def __validate_required_vars(self):
Expand All @@ -23,6 +24,10 @@ def config_file(self):
def vars(self):
return self._vars

@property
def additional_build_args(self):
return self._additional_build_args

@property
def secrets(self):
return self._secrets
Expand Down
6 changes: 5 additions & 1 deletion firestarter/tests/test_build_images_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"platforms": "linux/amd64,linux/arm64",
}
secrets = {}
additional_build_args = {}
config_file_path = f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/build_images.yaml"

with open(config_file_path, 'r') as config_file:
Expand Down Expand Up @@ -57,7 +58,10 @@ def reset_builder_value() -> None:
global builder

builder = BuildImages(
vars=vars, secrets=secrets, config_file=config_file_path
vars=vars,
secrets=secrets,
additional_build_args=additional_build_args,
config_file=config_file_path
)


Expand Down
17 changes: 16 additions & 1 deletion firestarter/workflows/build_images/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Beyond the configuration file which is mandatory, there are some other extra var
Additionally there are some optional variables:

* `container_structure_filename`: path of the [container-structure-test](https://github.com/GoogleContainerTools/container-structure-test) filename (if not set, no tests are checked)

> Highly recommended! ⚠️
* `publish`: publish the docker image to the registry

Expand All @@ -44,6 +44,21 @@ RUN --mount=type=secret,id=github_token,dst=/run/secrets/github_token \

> Remember to make sure the secret key name and secret id are the same


## Additional build args

In addition to those found in the configuration file, additional build args may be set using the command line argument `--additional-build-args` or via the `INPUT_ADDITIONAL_BUILD_ARGS` environment variable. These values can then be used in the Dockerfile, for example:

```Dockerfile
ARG YOUR_BUILD_ARG
ENV YOUR_BUILD_ARG=$YOUR_BUILD_ARG

RUN echo "The additional build arg is: $YOUR_BUILD_ARG"
```

> [!WARNING]
> Secrets and build args set in the configuration file will overwrite those set via the command line or environment variables.

## Example

1. Create a repository that uses run-dagger-py (check [docs](https://github.com/prefapp/run-dagger-py/blob/main/docs/index.md) for more details).
Expand Down
9 changes: 7 additions & 2 deletions firestarter/workflows/build_images/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@

logger = logging.getLogger(__name__)

def run(*, vars: dict, secrets: dict, config_file:str):
def run(*, vars: dict, secrets: dict, additional_build_args: dict, config_file:str):
try:
wf = BuildImages(vars=vars, secrets=secrets, config_file=config_file)
wf = BuildImages(
vars=vars,
secrets=secrets,
additional_build_args=additional_build_args,
config_file=config_file
)
return wf.execute()
except Exception as e:
logger.exception("Fatal error encountered during BuildImages execution.")
Expand Down
25 changes: 24 additions & 1 deletion firestarter/workflows/build_images/build_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,16 @@ async def compile_images_for_all_flavors(self):
f"Using these secrets for all flavors: {self.secrets.keys()}"
)

build_args_for_all_flavors = []
for key, value in self.additional_build_args.items():
build_args_for_all_flavors.append(
dagger.BuildArg(name=key, value=value)
)

logger.info(
f"Using these build_args for all flavors: {self.additional_build_args.keys()}"
)

for flavor in self.flavors:
registry, full_repo_name, build_args,\
dockerfile, extra_registries,\
Expand Down Expand Up @@ -416,6 +426,14 @@ async def compile_images_for_all_flavors(self):
for key, value in build_args.items()
]

# Combine generic and custom build_args for this flavor
# (Order matters: the args added in the second array will
# overwrite the ones with the same name in the first array.
# In this case, args defined in the flavor configuration will
# overwrite the same args defined as command line arguments
# or environment variables)
full_build_args = build_args_for_all_flavors + build_args_list

Comment thread
juanjosevazquezgil marked this conversation as resolved.
resolved_secret_refs = self.resolve_secrets(
self.config.images[flavor].secrets or {}
)
Expand All @@ -433,6 +451,11 @@ async def compile_images_for_all_flavors(self):
flavor_secrets.append(client.set_secret(key, value))

# Combine generic and custom secrets for this flavor
# (Order matters: the secrets added in the second array will
# overwrite the ones with the same name in the first array.
# In this case, secretss defined in the flavor configuration
# will overwrite the same secrets defined as command line
# arguments or environment variables)
secrets = secrets_for_all_flavors + flavor_secrets

# Set the address for the default registry
Expand Down Expand Up @@ -471,7 +494,7 @@ async def compile_images_for_all_flavors(self):
for image in registry_list:
await self.compile_image_and_publish(
client,
build_args_list,
full_build_args,
secrets,
dockerfile,
image,
Expand Down
Loading