Compare commits

..

No commits in common. "main" and "v0.1.0" have entirely different histories.
main ... v0.1.0

24 changed files with 530 additions and 666 deletions

View file

@ -7,7 +7,7 @@
"features": { "features": {
"ghcr.io/devcontainers/features/python:1": { "ghcr.io/devcontainers/features/python:1": {
"installTools": true, "installTools": true,
"version": "3.13" "version": "3.11"
}, },
"ghcr.io/devcontainers-contrib/features/black:2": { "ghcr.io/devcontainers-contrib/features/black:2": {
"version": "24.4.1" "version": "24.4.1"

17
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,17 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot
version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: weekly
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View file

@ -16,7 +16,7 @@ jobs:
release-please: release-please:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: google-github-actions/release-please-action@e4dc86ba9405554aeba3c6bb2d169500e7d3b4ee # v4 - uses: google-github-actions/release-please-action@v4
id: release-please id: release-please
with: with:
release-type: simple release-type: simple

View file

@ -1,25 +1,19 @@
aggrid aggrid
AKMODS
CHACHA CHACHA
configmap configmap
Containerfile Containerfile
containerignore containerignore
devcontainer devcontainer
devcontainers devcontainers
dialtimeout
dotenv dotenv
ENDCOLOR ENDCOLOR
ensurepath ensurepath
envsubst envsubst
filepicker filepicker
forwardingtimeouts
getent getent
gitmessage gitmessage
HHMMSS
hostvars hostvars
humanfriendly humanfriendly
idleconntimeout
idletimeout
keygen keygen
LAZYGIT LAZYGIT
lightspeed lightspeed
@ -36,13 +30,10 @@ notranslate
pipx pipx
posix posix
Proto Proto
readtimeout
redirections redirections
refreshable refreshable
rvproxy rvproxy
serverstransport serverstransport
serverstransports
silverblue
traefik traefik
ublue ublue
varnames varnames
@ -50,4 +41,3 @@ venvs
VIRTUALENVS VIRTUALENVS
wantlist wantlist
websecure websecure
writetimeout

View file

@ -1,38 +1,5 @@
# Changelog # Changelog
## [0.2.1](https://github.com/ublue-os/forge/compare/v0.2.0...v0.2.1) (2025-02-21)
### Bug Fixes
* **deps:** update dependency ansible-core to v2.18.2 ([e0f7d5f](https://github.com/ublue-os/forge/commit/e0f7d5fe43db8c0ac8e473232e884cdca75cd3e3))
* **deps:** update dependency humanize to v4.11.0 ([a32d754](https://github.com/ublue-os/forge/commit/a32d754c70c74c3193c09cde97ba34b6553c6903))
* **deps:** update dependency humanize to v4.12.1 ([c5d6cb0](https://github.com/ublue-os/forge/commit/c5d6cb072542cc9632e5d4b934b0c084224b3aca))
* **deps:** update dependency nicegui to v1.4.37 ([46202de](https://github.com/ublue-os/forge/commit/46202de6ba15671a6b3ae0c0bedf1199a496b9a6))
* **deps:** update dependency nicegui to v2 ([a043aa9](https://github.com/ublue-os/forge/commit/a043aa9ecc1e9a0bd645427a31e766f2611e0547))
* **deps:** update dependency nicegui to v2.10.0 ([8345361](https://github.com/ublue-os/forge/commit/8345361fccc43a1362005b32359c816e3fa33506))
* **deps:** update dependency nicegui to v2.10.1 ([e70dc98](https://github.com/ublue-os/forge/commit/e70dc983a8cb437824007e69e22ae2aa15b7562d))
* **deps:** update dependency nicegui to v2.9.1 [security] ([725673e](https://github.com/ublue-os/forge/commit/725673e5e7901778ad2154e5991c31b0616effbd))
* **deps:** update dependency pandas to v2.2.3 ([37137ef](https://github.com/ublue-os/forge/commit/37137ef32bdebcaa3dcedcc1ce7aecb0bba32f19))
## [0.2.0](https://github.com/ublue-os/forge/compare/v0.1.0...v0.2.0) (2024-05-27)
### Features
* **ansible:** add additional tags to container image ([6297b8f](https://github.com/ublue-os/forge/commit/6297b8f951eaa597d2499116a1f4ab0c0ff0fa8c))
* **ansible:** add example configurations to the setup ([#45](https://github.com/ublue-os/forge/issues/45)) ([e0df500](https://github.com/ublue-os/forge/commit/e0df50076e6067ad65588a7bfe77818470b495c6))
* **ansible:** add possibility to add build-args to podman build job ([#51](https://github.com/ublue-os/forge/issues/51)) ([cec7512](https://github.com/ublue-os/forge/commit/cec7512c570dd100d87b079c350440207abafde9))
* **nicegui:** easy navigation to home ([327c010](https://github.com/ublue-os/forge/commit/327c010ddddc62dfb7873adfe0b36d14ed567e2e))
* **nicegui:** make image table sortable ([af3bdc3](https://github.com/ublue-os/forge/commit/af3bdc37fb4d8b65043981257e942dfd8ba6651d))
### Bug Fixes
* **ansible:** use registry url for container image name ([d1a0f7f](https://github.com/ublue-os/forge/commit/d1a0f7fff2be3854a9b6765dea77eedb529f42a3))
* **nicegui:** empty image table should use same column names as when images are available ([ae10ebc](https://github.com/ublue-os/forge/commit/ae10ebc4acdf8e9bfab792cb2dbcaa22257c00d1))
* **registry:** disable performance constraints ([#52](https://github.com/ublue-os/forge/issues/52)) ([b213c82](https://github.com/ublue-os/forge/commit/b213c826cf224b5a21d45dcf3c0b5ef526f22ecd))
## 0.1.0 (2024-05-24) ## 0.1.0 (2024-05-24)

View file

@ -1,5 +1,5 @@
# Source Image # Source Image
FROM docker.io/library/python:3.13-alpine3.19@sha256:8287ca207e905649e9f399b5f91a119e5e9051d8cd110d5f8c3b4bd9458ebd1d FROM docker.io/library/python:3.11-alpine3.19
# Environment vars # Environment vars
ENV PROJECT_DIR="/anvil" ENV PROJECT_DIR="/anvil"

View file

@ -1,8 +1,8 @@
--- ---
collections: collections:
- name: ansible.posix - name: ansible.posix
version: 2.0.0 version: 1.5.4
- name: community.general - name: community.general
version: 10.5.0 version: 8.6.0
- name: containers.podman - name: containers.podman
version: 1.16.3 version: 1.13.0

View file

@ -1,6 +1,3 @@
--- ---
forge_container_name: "{{ forge_registry_url }}/{{ forge_git_repository_url | regex_search('(?<=/)[^/]+(?=\\.git)') }}"
forge_container_tag: "{{ ansible_date_time.date }}_{{ ansible_date_time.time | replace(':','')}}"
forge_container_file: "Containerfile" forge_container_file: "Containerfile"
forge_container_format: "oci" forge_container_format: "oci"
forge_container_extra_args: []

View file

@ -1,5 +1,5 @@
--- ---
# git variables # git variables
forge_git_repository_url: "" forge_git_repository_url: "https://github.com/ublue-os/bluefin.git"
forge_git_repository_destination: "" forge_git_repository_destination: "{{ forge_data_volume_mountpoint }}/data/bluefin"
forge_git_repository_version: "main" forge_git_repository_version: "main"

View file

@ -36,19 +36,19 @@
changed_when: false changed_when: false
become: true become: true
- name: Create example directory - name: Create example extra-vars configuration file
ansible.builtin.file: ansible.builtin.copy:
path: "{{ forge_data_volume_mountpoint }}/examples/" dest: "{{ forge_data_volume_mountpoint }}/forge_example_vars.yml"
state: directory content: |
mode: "0755" ## ublue-os forge extra-vars example configuration
## For more details got to https://github.com/ublue-os/forge/blob/main/docs/variables.md
- name: Create example configuration files ---
ansible.builtin.template: {% for item in __vars_used %}
src: "{{ item }}" {{ item }}: {{ lookup('ansible.builtin.vars', item) }}
dest: "{{ forge_data_volume_mountpoint }}/examples/{{ item | regex_search(__regex_search) }}" {% endfor %}
backup: true backup: true
owner: "{{ ansible_facts.env.USER }}" owner: "{{ ansible_facts.env.USER }}"
mode: "0644" mode: "0644"
with_fileglob: "files/examples/*"
vars: vars:
__regex_search: "[^\/]+$" __vars_used: "{{ lookup('ansible.builtin.varnames', __regex_search, wantlist=true) }}"
__regex_search: ^forge_(?!data).+

View file

@ -1,11 +0,0 @@
## ublue-os forge example configuration for bluefin
## For more details got to https://github.com/ublue-os/forge/blob/main/docs/variables.md
---
forge_git_repository_url: https://github.com/ublue-os/bluefin.git
forge_git_repository_destination: "{{ forge_data_volume_mountpoint }}/data/bluefin"
forge_container_extra_args:
- --build-arg="BASE_IMAGE_NAME=silverblue"
- --build-arg="IMAGE_FLAVOR=main"
- --build-arg="AKMODS_FLAVOR=main"
- --build-arg="FEDORA_MAJOR_VERSION=39"
- --build-arg="TARGET_BASE=bluefin"

View file

@ -8,59 +8,34 @@
name: debug_forge_vars name: debug_forge_vars
tasks: tasks:
- name: Build and upload container image - name: Build and push image to registry
containers.podman.podman_image: containers.podman.podman_image:
name: "{{ forge_container_name }}" name: "{{ forge_git_repository_url | regex_search(__regex_search) }}"
tag: latest tag: latest
path: "{{ forge_git_repository_destination }}" path: "{{ forge_git_repository_destination }}"
build: build:
file: "{{ forge_container_file }}" file: "{{ forge_container_file | default('Containerfile') }}"
format: "{{ forge_container_format }}" format: "{{ forge_container_format | default('oci') }}"
extra_args: "{{ forge_container_extra_args | join(' ') }}"
pull: false pull: false
push: true push: true
async: 900 push_args:
dest: "{{ forge_registry_url }}"
vars:
__regex_search: (?<=/)[^/]+(?=\.git)
async: 1800
poll: 0 poll: 0
register: __podman_image register: __podman_image
- name: Waiting for container build and upload to finish - name: Waiting for container build to finish
ansible.builtin.async_status: ansible.builtin.async_status:
jid: "{{ __podman_image.ansible_job_id }}" jid: "{{ __podman_image.ansible_job_id }}"
register: __job_result register: __job_result
until: __job_result.finished until: __job_result.finished
retries: 900 retries: 1800
delay: 1 delay: 1
- name: INFO | Result from container image build - name: INFO | Status from build and push
ansible.builtin.debug: ansible.builtin.debug:
msg: msg:
- "{{ __job_result.actions | to_nice_yaml(indent=2) }}" - "{{ __job_result.actions | to_nice_yaml(indent=2) }}"
- "{{ __job_result.image | to_nice_yaml(indent=2) }}" - "{{ __job_result.image | to_nice_yaml(indent=2) }}"
- name: Add additional tag to container image
containers.podman.podman_tag:
image: "{{ forge_container_name }}:latest"
target_names:
- "{{ forge_container_name }}:{{ forge_container_tag }}"
- name: Push additional container image tag to registry
containers.podman.podman_image:
name: "{{ forge_container_name }}"
tag: "{{ forge_container_tag }}"
pull: false
push: true
async: 15
poll: 0
register: __podman_image
- name: Waiting for additional container image tag push to finish
ansible.builtin.async_status:
jid: "{{ __podman_image.ansible_job_id }}"
register: __job_result
until: __job_result.finished
retries: 15
delay: 1
- name: INFO | Result from additional container image tag push
ansible.builtin.debug:
msg: "{{ __job_result.actions | to_nice_yaml(indent=2) }}"

View file

@ -14,9 +14,7 @@ ANSIBLE_EXTRA_VARS = None
async def load_configuration_file() -> None: async def load_configuration_file() -> None:
global ANSIBLE_EXTRA_VARS global ANSIBLE_EXTRA_VARS
result = await local_file_picker( result = await local_file_picker(
directory="/data", directory="/data", multiple=False, file_name_filter=".yml"
multiple=False,
# file_name_filter=".yml", # TODO: limit to yml files but make sure folders are visible as well
) )
file_path = result[0] file_path = result[0]
with open(file_path, "r") as file: with open(file_path, "r") as file:

View file

@ -6,7 +6,7 @@ from utils.registry import DockerRegistry
## TODO: this should be async but I currently don't know how to implement this without button press ## TODO: this should be async but I currently don't know how to implement this without button press
def get_image_info() -> pandas.DataFrame: def get_image_info() -> pandas.DataFrame:
data = pandas.DataFrame(columns=["image", "tag", "size"]) data = pandas.DataFrame(columns=["image_name", "tag", "size"])
try: try:
registry = DockerRegistry() registry = DockerRegistry()
all_image_info = registry.get_all_image_info() all_image_info = registry.get_all_image_info()
@ -24,10 +24,8 @@ def get_image_info() -> pandas.DataFrame:
lambda layers: sum(layer["size"] for layer in layers) lambda layers: sum(layer["size"] for layer in layers)
) )
) )
data = ( data = data[["image_name", "name", "size"]].rename(
data[["image_name", "name", "size"]] columns={"image_name": "image", "name": "tag", "size": "size"}
.rename(columns={"image_name": "image", "name": "tag", "size": "size"})
.sort_values(by=["image", "tag"], ascending=False)
) )
data["size"] = data["size"].apply(humanize.naturalsize) data["size"] = data["size"].apply(humanize.naturalsize)
return data return data
@ -41,7 +39,4 @@ def content() -> None:
with ui.card().classes("w-full"): with ui.card().classes("w-full"):
ui.label("Image Overview").classes("text-h5") ui.label("Image Overview").classes("text-h5")
data = get_image_info() data = get_image_info()
with ui.table.from_pandas(df=data).classes("w-full") as table: ui.table.from_pandas(df=data).classes("w-full")
table.columns[0]["sortable"] = True
table.columns[1]["sortable"] = True
table.columns[2]["sortable"] = True

View file

@ -35,10 +35,9 @@ def frame(
with ui.grid(columns=3).classes("w-full gap-0"): with ui.grid(columns=3).classes("w-full gap-0"):
with ui.row(wrap=False).classes("col-span-1 justify-start"): with ui.row(wrap=False).classes("col-span-1 justify-start"):
menu() menu()
with ui.link(target="/"): ui.image(source=f"{project_root}/pages/assets/ublue-mini.svg").props(
ui.image( "width=33px hight=auto"
source=f"{project_root}/pages/assets/ublue-mini.svg" )
).props("width=33px hight=auto")
ui.label(text="Forge").classes("text-h5") ui.label(text="Forge").classes("text-h5")
with ui.row(wrap=False).classes("col-span-1 justify-center"): with ui.row(wrap=False).classes("col-span-1 justify-center"):
ui.label(text=navigation_title).classes("text-h5") ui.label(text=navigation_title).classes("text-h5")

942
anvil/poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -10,15 +10,15 @@ readme = "../README.md"
python = "^3.11" python = "^3.11"
ansible-core = "^2.16" ansible-core = "^2.16"
jmespath = "^1.0" jmespath = "^1.0"
nicegui = "^2.9.1" nicegui = "^1.4.23"
ansible-runner = "^2.3.6" ansible-runner = "^2.3.6"
requests = "^2.32.2" requests = "^2.31.0"
pandas = "^2.2.2" pandas = "^2.2.2"
humanize = "^4.9.0" humanize = "^4.9.0"
toml = "^0.10.2" toml = "^0.10.2"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
ansible-lint = { version = "25.2.1", markers = 'platform_system != "Windows"' } # https://github.com/ansible/ansible-lint/issues/2730#issuecomment-1330406601 ansible-lint = { version = "^24.2", markers = 'platform_system != "Windows"' } # https://github.com/ansible/ansible-lint/issues/2730#issuecomment-1330406601
[build-system] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]

View file

@ -41,24 +41,21 @@ ln -s $FORGE_POD_DATA_DIR $HOME/ublue-os_forge-data
With this the data folder would be available in your home directory under `~/ublue-os_forge-data` With this the data folder would be available in your home directory under `~/ublue-os_forge-data`
In that folder you will find an **examples** folder with example configurations similar to this: In that folder you will find an example configuration similar to this:
```yaml ```yaml
## ublue-os forge example configuration ## ublue-os forge extra-vars example configuration
## For more details got to https://github.com/ublue-os/forge/blob/main/docs/variables.md ## For more details got to https://github.com/ublue-os/forge/blob/main/docs/variables.md
--- ---
forge_git_repository_url: https://github.com/ublue-os/bluefin.git forge_git_repository_url: https://github.com/ublue-os/bluefin.git
forge_git_repository_destination: "/var/home/stephan/.local/share/containers/storage/volumes/ublue-os_forge-data/_data/data/bluefin" forge_git_repository_destination: /var/home/stephan/.local/share/containers/storage/volumes/ublue-os_forge-data/_data/data/bluefin
forge_container_extra_args: forge_git_repository_version: main
- --build-arg="BASE_IMAGE_NAME=silverblue" forge_registry_url: registry.ublue.local
- --build-arg="IMAGE_FLAVOR=main"
- --build-arg="AKMODS_FLAVOR=main"
- --build-arg="FEDORA_MAJOR_VERSION=39"
- --build-arg="TARGET_BASE=bluefin"
``` ```
These files are a good starting point for your custom configuration. Simple copy those examples This file acts as a template. It has all available settings outlined for you. Simple copy
you are interested in modify them to your liking. it and modify it to your liking. For each project you want to handle with the forge you can
create a dedicated file.
Details about the available variables are documented [here](./variables.md). Details about the available variables are documented [here](./variables.md).

View file

@ -11,15 +11,15 @@ The following configuration variables are available and can be set to your likin
<!-- markdownlint-disable MD013 --> <!-- markdownlint-disable MD013 -->
| Name | Type | Default value | Description | | Name | Type | Default value | Description |
| ---------------------------------- | ---- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | ---------------------------------- | ---- | ------------------------------------------------- | -------------------------------------------------------------------------------- |
| `forge_container_name` | str | Project name derived from `forge_git_repository_url` Example: `bluefin` | Container image name. |
| `forge_container_tag` | str | Evaluates to: `YYY-MM-DD_HHMMSS` Example: `2024-05-26_192206` | Container image tag. |
| `forge_container_file` | str | Containerfile | Path to the Containerfile for Podman to build | | `forge_container_file` | str | Containerfile | Path to the Containerfile for Podman to build |
| `forge_container_format` | str | oci | Format of the image Podman will build. Can be either `oci` or `docker` | | `forge_container_format` | str | oci | Format of the image Podman will build. Can be either `oci` or `docker` |
| `forge_container_extra_args` | list | [] | List of extra arguments which gets passed to the podman build process. Example: `[--build-arg="BASE_IMAGE_NAME=silverblue"]` | | `forge_git_repository_url` | str | <https://github.com/ublue-os/bluefin.git> | Git repository url |
| `forge_git_repository_url` | str | | Git repository url | | `forge_git_repository_destination` | str | `{{ forge_data_volume_mountpoint }}`/data/bluefin | Git destination where repository is cloned to. Can be any directory on your host |
| `forge_git_repository_destination` | str | | Git destination where repository is cloned to. |
| `forge_git_repository_version` | str | main | Git repository branch or tag or commit version | | `forge_git_repository_version` | str | main | Git repository branch or tag or commit version |
| `forge_registry_url` | str | registry.ublue.local | Container registry url | | `forge_registry_url` | str | registry.ublue.local | Container registry url |
<!-- markdownlint-enable MD013--> <!-- markdownlint-enable MD013-->
**_Note:_** The `{{ forge_data_volume_mountpoint }}` points to your ublue-os_forge-data
podman volume.

View file

@ -27,6 +27,10 @@ spec:
containers: containers:
- name: traefik.${FORGE_DOMAIN_NAME} - name: traefik.${FORGE_DOMAIN_NAME}
image: traefik # will be built on pod start image: traefik # will be built on pod start
resources:
limits:
memory: 128Mi
cpu: 200m
volumeMounts: volumeMounts:
- mountPath: /var/run/podman.sock - mountPath: /var/run/podman.sock
name: podman-socket name: podman-socket
@ -73,6 +77,10 @@ spec:
containers: containers:
- name: docker.${FORGE_DOMAIN_NAME} - name: docker.${FORGE_DOMAIN_NAME}
image: registry # will be built on pod start image: registry # will be built on pod start
resources:
limits:
memory: 512Mi
cpu: 200m
volumeMounts: volumeMounts:
- mountPath: /certs - mountPath: /certs
name: ublue-os_forge-certs-pvc name: ublue-os_forge-certs-pvc

View file

@ -1,5 +1,5 @@
# Source Image # Source Image
FROM docker.io/library/golang:1.24@sha256:d9db32125db0c3a680cfb7a1afcaefb89c898a075ec148fdc2f0f646cc2ed509 FROM docker.io/library/golang:1.20
# Copy script # Copy script
WORKDIR /certs WORKDIR /certs

View file

@ -1,5 +1,5 @@
# Source Image # Source Image
FROM docker.io/library/registry:3.0@sha256:1fc7de654f2ac1247f0b67e8a459e273b0993be7d2beda1f3f56fbf1001ed3e7 FROM docker.io/library/registry:2.8
# Configure TLS certificates # Configure TLS certificates
ENV REGISTRY_HTTP_TLS_CERTIFICATE="/certs/cert.pem" ENV REGISTRY_HTTP_TLS_CERTIFICATE="/certs/cert.pem"

View file

@ -1,6 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}

View file

@ -1,5 +1,5 @@
# Source Image # Source Image
FROM docker.io/traefik:v3.3@sha256:83f3c843133530e4aa45e6ddc415488583a8a01c88adc5022d415c6e97ceeaae FROM docker.io/traefik:v2.11
# Add configuration file # Add configuration file
COPY ./config/*.yml /etc/traefik/ COPY ./config/*.yml /etc/traefik/