From b5e96759188581adefc3b13dac1da412a11db4d9 Mon Sep 17 00:00:00 2001 From: Blallo Date: Tue, 23 Feb 2021 00:01:03 +0100 Subject: [PATCH] Add piker --- .gitignore | 3 + piker.yml | 9 ++ piker/__init__.py | 3 + piker/piker.py | 57 ++++++++ piker/template/drone.yml.j2 | 260 ++++++++++++++++++++++++++++++++++++ setup.py | 24 ++++ 6 files changed, 356 insertions(+) create mode 100644 .gitignore create mode 100644 piker.yml create mode 100644 piker/__init__.py create mode 100644 piker/piker.py create mode 100644 piker/template/drone.yml.j2 create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2b490e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.egg-info/ +ve/ +__pycache__/ diff --git a/piker.yml b/piker.yml new file mode 100644 index 0000000..67dcd24 --- /dev/null +++ b/piker.yml @@ -0,0 +1,9 @@ +--- +base_path: /var/builds/archlinux +mailer_version: "0.5-1" +pikaur_version: "0.3" +user_uid: 1000 +user_gid: 33 +pkgs: + - electron-ozone + - discord_arch_electron diff --git a/piker/__init__.py b/piker/__init__.py new file mode 100644 index 0000000..1519707 --- /dev/null +++ b/piker/__init__.py @@ -0,0 +1,3 @@ +# -*- encoding: utf-8 -*- + +from piker.piker import * diff --git a/piker/piker.py b/piker/piker.py new file mode 100644 index 0000000..2fb8f9c --- /dev/null +++ b/piker/piker.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- + +import os.path +import typing as T + +import click +import jinja2 +import yaml + + +def read_config(path: T.Text) -> T.Dict[T.Text, T.Any]: + """ + Read the config from the specified path + """ + if not os.path.exists(path): + raise ValueError(f"File does not exist {path}") + + with open(path) as f: + data = yaml.safe_load(f) + + if not isinstance(data, dict): + raise ValueError(f"Malformed configuration") + + return data + + +def render_template(data: T.Dict[T.Text, T.Any], path: T.Text, dry_run: bool) -> None: + """ + Given the configuration values, renders the template into the desired path. + """ + loader = jinja2.PackageLoader("piker", "template") + env = jinja2.Environment( + loader=loader, autoescape=jinja2.select_autoescape(["yaml"]) + ) + template = env.get_template("drone.yml.j2") + value = template.render(**data) + if dry_run: + print(value) + return + with open(path, "w") as out: + out.write(value) + + +@click.command() +@click.option( + "--dry-run/--no-dry-run", + default=False, + help="Display result without actually writing it", +) +@click.argument("config", type=click.Path(exists=True), default="./piker.yml") +@click.argument("target", type=click.Path(), default="./.drone.yml") +def cli(dry_run: bool, config: T.Text, target: T.Text) -> None: + """ + CLI entrypoint + """ + conf_data = read_config(config) + render_template(conf_data, target, dry_run) diff --git a/piker/template/drone.yml.j2 b/piker/template/drone.yml.j2 new file mode 100644 index 0000000..f0f79ab --- /dev/null +++ b/piker/template/drone.yml.j2 @@ -0,0 +1,260 @@ +--- +kind: pipeline +type: docker +name: pre_clean + +platform: + os: linux + arch: amd64 + +workspace: + path: /drone + +steps: +- name: remove-locks + pull: if-not-exists + image: leophys/pikaur:{{ pikaur_version }} + user: root + commands: + - rm -f /output/lock + volumes: + - name: output + path: /output + +volumes: +- name: output + host: + path: {{ base_path }}/output + +{% for pkg in pkgs %} +--- +kind: pipeline +type: docker +name: {{ pkg }} + +platform: + os: linux + arch: amd64 + +workspace: + path: /drone + +steps: +- name: cache-init_{{ pkg }} + pull: if-not-exists + image: leophys/pikaur:{{ pikaur_version }} + user: root + commands: + - | + if ! [ "$(ls -A /cache_stage/etc)" ]; then + cp -r /etc/. /cache_stage/etc/ + getfacl -p -R /etc > /cache_stage/etc/permissions.acl + fi + - | + if ! [ "$(ls -A /cache_stage/opt)" ]; then + cp -r /opt/. /cache_stage/opt/ + getfacl -p -R /opt > /cache_stage/opt/permissions.acl + fi + - | + if ! [ "$(ls -A /cache_stage/var)" ]; then + cp -r /var/. /cache_stage/var/ + getfacl -p -R /var > /cache_stage/var/permissions.acl + fi + - | + if ! [ "$(ls -A /cache_stage/usr)" ]; then + cp -r /usr/. /cache_stage/usr/ + getfacl -p -R /usr > /cache_stage/usr/permissions.acl + fi + - | + if ! [ "$(ls -A /build2)" ]; then + cp -r /build/. /build2/ + getfacl -p -R /usr > /build2/permissions.acl + fi + - chmod a+rw /output + volumes: + - name: build_{{ pkg }} + path: /build2 + - name: etc_{{ pkg }} + path: /cache_stage/etc + - name: opt_{{ pkg }} + path: /cache_stage/opt + - name: var_{{ pkg }} + path: /cache_stage/var + - name: usr_{{ pkg }} + path: /cache_stage/usr + - name: output + path: /output + +- name: cache-acl_{{ pkg }} + pull: if-not-exists + image: leophys/pikaur:{{ pikaur_version }} + user: root + commands: + - setfacl --restore=/etc/permissions.acl + - setfacl --restore=/opt/permissions.acl + - setfacl --restore=/var/permissions.acl + - setfacl --restore=/usr/permissions.acl + - setfacl --restore=/build/permissions.acl + - chown -R {{ user_uid }}:{{ user_gid }} /build + volumes: + - name: build_{{ pkg }} + path: /build + - name: etc_{{ pkg }} + path: /etc + - name: opt_{{ pkg }} + path: /opt + - name: var_{{ pkg }} + path: /var + - name: usr_{{ pkg }} + path: /usr + +- name: build_{{ pkg }} + pull: if-not-exists + image: leophys/pikaur:{{ pikaur_version }} + commands: + - | + if [ -f /output/lock ]; then + while [ -f /output/lock ]; do + sleep 10 + echo "Waiting $(cat /output/lock)" + done + else + echo "{{ pkg }}" >> /output/lock + fi + - | + set -euo pipefail + /usr/bin/pikaur -G --noconfirm {{ pkg }}|tee /output/{{ pkg }}.log + /usr/bin/pikaur -Py --keepbuilddeps --noconfirm {{ pkg }}/PKGBUILD|tee /output/{{ pkg }}.log + - rm -f /output/lock + volumes: + - name: build_{{ pkg }} + path: /build + - name: etc_{{ pkg }} + path: /etc + - name: opt_{{ pkg }} + path: /opt + - name: var_{{ pkg }} + path: /var + - name: usr_{{ pkg }} + path: /usr + - name: output + path: /output + +volumes: +- name: build_{{ pkg }} + host: + path: {{ base_path }}/{{ pkg }} +- name: etc_{{ pkg }} + host: + path: {{ base_path }}/etc/{{ pkg }} +- name: opt_{{ pkg }} + host: + path: {{ base_path }}/opt/{{ pkg }} +- name: var_{{ pkg }} + host: + path: {{ base_path }}/var/{{ pkg }} +- name: usr_{{ pkg }} + host: + path: {{ base_path }}/usr/{{ pkg }} +- name: output + host: + path: {{ base_path }}/output + +trigger: + branch: + - master + event: + - push + - cron + +depends_on: + - pre_clean + +--- +kind: pipeline +type: docker +name: notify_failure-{{ pkg }} + +clone: + disable: true + +steps: +- name: notify_failure + pull: if-not-exists + image: leophys/mailer:{{ mailer_version }} + environment: + M_SERVER_ADDRESS: + from_secret: m_server_address + M_USER: + from_secret: m_user + M_PASSWORD: + from_secret: m_password + M_FROM: + from_secret: m_from + M_TO: + from_secret: m_to + M_SUB: "[{{ pkg }}] FAILURE" + commands: + - /sendmail.sh /output/{{ pkg }}.log + volumes: + - name: output + path: /output + +- name: clean_lock + pull: if-not-exists + image: leophys/pikaur:{{ pikaur_version }} + user: root + commands: + - rm -f /output/lock + volumes: + - name: output + path: /output + +volumes: +- name: output + host: + path: {{ base_path }}/output + +trigger: + status: + - failure + +depends_on: + - {{ pkg }} + +{% endfor %} + +--- +kind: pipeline +type: docker +name: notify_success + +clone: + disable: true + +steps: +- name: notify_success + pull: if-not-exists + image: leophys/mailer:{{ mailer_version }} + environment: + M_SERVER_ADDRESS: + from_secret: m_server_address + M_USER: + from_secret: m_user + M_PASSWORD: + from_secret: m_password + M_FROM: + from_secret: m_from + M_TO: + from_secret: m_to + M_SUB: "[archlinux] SUCCESS" + M_TEXT: "Success building archlinux packages" + +trigger: + status: + - success + +depends_on: +{%- for pkg in pkgs %} + - {{ pkg }} +{%- endfor %} diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0708da3 --- /dev/null +++ b/setup.py @@ -0,0 +1,24 @@ +# -*- encoding: utf-8 -*- + +from distutils.core import setup + +descr = "Generate drone files from template to build archlinux packages from AUR" +requirements = [ + "Click", + "Jinja2", + "PyYAML", +] + +setup( + name="piker", + version="0.1", + description=descr, + packages=["piker"], + package_dir={"piker": "piker"}, + package_data={"piker": ["templates/drone.yml.j2"]}, + install_requires=requirements, + entry_points=""" + [console_scripts] + piker=piker:cli + """, +)