Sergio Talens-Oliag Technical Blog

Mixinet BlogOps

Command line tools to process templates

I’ve always been a fan of template engines that work with text files, mainly to work with static site generators, but also to generate code, configuration files, and other text-based files. For my own web projects I used to go with Jinja2, as all my projects were written in Python, while for static web sites I used the template engines included with the tools I was using, i.e. Liquid with Jekyll and Go Templates (based on the text/template and the html/template go packages) for Hugo. When I needed to generate code snippets or configuration files from shell scripts I used to go with sed and/or envsubst, but lately things got complicated and I started to use a command line application called tmpl that uses the Go Template Language with functions from the Sprig library. tmplI’ve been using my fork of the tmpl program to process templates on CI/CD pipelines (gitlab-ci) to generate configuration files and code snippets because it uses the same syntax used by helm (easier to use by other DevOps already familiar with the format) and the binary is small and can be easily included into the docker images used by the pipeline jobs. One interesting feature of the tmpl tool is that it can read values from command line arguments and from multiple files in different formats (YAML, JSON, TOML, etc) and merge them into a single object that can be used to render the templates. There are alternatives to the tmpl tool and I’ve looked at them (i.e. simple ones like go-template-cli or complex ones like gomplate), but I haven’t found one that fits my needs. For my next project I plan to evaluate a move to a different tool or template format, as tmpl is not being actively maintained (as I said, I’m using my own fork) and it is not included on existing GNU/Linux distributions (I packaged it for Debian and Alpine, but I don’t want to maintain something like that without an active community and I’m not interested in being the upstream myself, as I’m trying to move to Rust instead of Go as the compiled programming language for my projects). Mini JinjaLooking for alternate tools to process templates on the command line I found the minijinja rust crate, a minimal implementation of the Jinja2 template engine that also includes a small command line utility (minijinja-cli) and I believe I’ll give it a try on the future for various reasons: I’m already familiar with the Jinja2 syntax and it is widely used on the industry.On my code I can use the original Jinja2 module for Python projects and MiniJinja for Rust programs.The included command line utility is small and easy to use, and the binaries distributed by the project are good enough to add them to the docker container images used by CI/CD pipelines.As I want to move to Rust I can try to add functionalities to the existing command line client or create my own version of it if they are needed (don’t think so, but who knows)....

January 16, 2025 · 3 min

Testing New User Tools

On recent weeks I’ve had some time to scratch my own itch on matters related to tools I use daily on my computer, namely the desktop / window manager and my text editor of choice. This post is a summary of what I tried, how it worked out and my short and medium-term plans related to them. Desktop / WMOn the desktop / window manager front I’ve been using Cinnamon on Debian and Ubuntu systems since Gnome 3 was published (I never liked version 3, so I decided to move to something similar to Gnome 2, including the keyboard shortcuts). In fact I’ve never been a fan of Desktop environments, before Gnome I used OpenBox and IceWM because they where a lot faster than desktop systems on my hardware at the time and I was using them only to place one or two windows on multiple workspaces using mainly the keyboard for my interactions (well, except for the web browsers and the image manipulation programs). Although I was comfortable using Cinnamon, some years ago I tried to move to i3, a tilling window manager for X11 that looked like a good choice for me, but I didn’t have much time to play with it and never used it enough to make me productive with it (I didn’t prepare a complete configuration nor had enough time to learn the new shortcuts, so I went back to Cinnamon and never tried again). Anyway, some weeks ago I updated my work machine OS (it was using Ubuntu 22.04 LTS and I updated it to the 24.04 LTS version) and the Cinnamon systray applet stopped working as it used to do (in fact I still have to restart Cinnamon after starting a session to make it work) and, as I had some time, I decided to try a tilling window manager again, but now I decided to go for SwayWM, as it uses Wayland instead of X11. Sway configurationOn my ~/.config/sway/config I tuned some things: Set fuzzel as the application launcher.Installed manually the shikane application and created a configuration to be executed always when sway is started / reloaded (I adjusted my configuration with wdisplays and used shikanectl to save it).Added support for running the xdg-desktop-portal-wlr service.Enabled the swayidle command to lock the screen after some time of inactivity.Adjusted the keyboard to use the es key mapAdded some keybindings to make my life easier, including the use of grimm and swappy to take screenshotsConfigured waybar as the environment bar.Added a shell script to start applications when sway is started (it uses swaymsg to execute background commands and the i3toolwait script to wait for the #!/bin/sh # VARIABLES CHROMIUM_LOCAL_STATE="$HOME/.config/google-chrome/Local State" I3_TOOLWAIT="$HOME/.config/sway/scripts/i3-toolwait" # Functions chromium_profile_dir() { jq -r ".profile.info_cache|to_entries|map({(.value.name): .key})|add|.\"$1\" // \"\"" "$CHROMIUM_LOCAL_STATE" } # MAIN IGZ_PROFILE_DIR="$(chromium_profile_dir "sergio.talens@intelygenz.com")" OURO_PROFILE_DIR="$(chromium_profile_dir "sergio.talens@nxr.global")" PERSONAL_PROFILE_DIR="$(chromium_profile_dir "stalens@gmail.com")" # Common programs swaymsg "exec nextcloud --background" swaymsg "exec nm-applet" # Run spotify on the first workspace (it is mapped to the laptop screen) swaymsg -q "workspace 1" ${I3_TOOLWAIT} "spotify" # Run tmux on the swaymsg -q "workspace 2" ${I3_TOOLWAIT} -- foot tmux a -dt sto wp_num="3" if [ "$OURO_PROFILE_DIR" ]; then swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} -m ouro-browser -- google-chrome --profile-directory="$OURO_PROFILE_DIR" wp_num="$((wp_num+1))" fi if [ "$IGZ_PROFILE_DIR" ]; then swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} -m igz-browser -- google-chrome --profile-directory="$IGZ_PROFILE_DIR" wp_num="$((wp_num+1))" fi if [ "$PERSONAL_PROFILE_DIR" ]; then swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} -m personal-browser -- google-chrome --profile-directory="$PERSONAL_PROFILE_DIR" wp_num="$((wp_num+1))" fi # Open the browser without setting the profile directory if none was found if [ "$wp_num" = "3" ]; then swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} google-chrome wp_num="$((wp_num+1))" fi swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} evolution wp_num="$((wp_num+1))" swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} slack wp_num="$((wp_num+1))" # Open a private browser and a console in the last workspace swaymsg -q "workspace $wp_num" ${I3_TOOLWAIT} -- google-chrome --incognito ${I3_TOOLWAIT} foot # Go back to the second workspace for keepassxc swaymsg "workspace 2" ${I3_TOOLWAIT} keepassxc...

January 10, 2025 · 10 min

GitLab CI/CD Tips: Automatic Versioning Using semantic-release

This post describes how I’m using semantic-release on gitlab-ci to manage versioning automatically for different kinds of projects following a simple workflow (a develop branch where changes are added or merged to test new versions, a temporary release/#.#.# to generate the release candidate versions and a main branch where the final versions are published). What is semantic-releaseIt is a Node.js application designed to manage project versioning information on Git Repositories using a Continuous integration system (in this post we will use gitlab-ci) How does it workBy default semantic-release uses semver for versioning (release versions use the format MAJOR.MINOR.PATCH) and commit messages are parsed to determine the next version number to publish. If after analyzing the commits the version number has to be changed, the command updates the files we tell it to (i.e. the package.json file for nodejs projects and possibly a CHANGELOG.md file), creates a new commit with the changed files, creates a tag with the new version and pushes the changes to the repository. When running on a CI/CD system we usually generate the artifacts related to a release (a package, a container image, etc.) from the tag, as it includes the right version number and usually has passed all the required tests (it is a good idea to run the tests again in any case, as someone could create a tag manually or we could run extra jobs when building the final assets …​ if they fail it is not a big issue anyway, numbers are cheap and infinite, so we can skip releases if needed). Commit messages and versioningThe commit messages must follow a known format, the default module used to analyze them uses the angular git commit guidelines, but I prefer the conventional commits one, mainly because it’s a lot easier to use when you want to update the MAJOR version. The commit message format used must be: <type>(optional scope): <description> [optional body] [optional footer(s)]...

December 26, 2023 · 14 min

GitLab CI/CD Tips: Using Rule Templates

This post describes how to define and use rule templates with semantic names using extends or !reference tags, how to define manual jobs using the same templates and how to use gitlab-ci inputs as macros to give names to regular expressions used by rules. Basic rule templatesI keep my templates in a rules.yml file stored on a common repository used from different projects as I mentioned on my previous post, but they can be defined anywhere, the important thing is that the files that need them include their definition somehow. The first version of my rules.yml file was as follows: .rules_common: # Common rules; we include them from others instead of forcing a workflow rules: # Disable branch pipelines while there is an open merge request from it - if: >- $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE != "merge_request_event" when: never .rules_default: # Default rules, we need to add the when: on_success to make things work rules: - !reference [.rules_common, rules] - when: on_success...

September 24, 2023 · 8 min

GitLab CI/CD Tips: Using a Common CI Repository with Assets

This post describes how to handle files that are used as assets by jobs and pipelines defined on a common gitlab-ci repository when we include those definitions from a different project. Problem descriptionWhen a .giltlab-ci.yml file includes files from a different repository its contents are expanded and the resulting code is the same as the one generated when the included files are local to the repository. In fact, even when the remote files include other files everything works right, as they are also expanded (see the description of how included files are merged for a complete explanation), allowing us to organise the common repository as we want. As an example, suppose that we have the following script on the assets/ folder of the common repository: dumb.sh #!/bin/sh echo "The script arguments are: '$@'" If we run the following job on the common repository: job: script: - $CI_PROJECT_DIR/assets/dumb.sh ARG1 ARG2...

September 17, 2023 · 8 min