Jekyll2024-02-03T04:11:05-06:00https://josecastillolema.github.io/feed.xmlGitOpsNetworks, SDN, NFVi, OpenStack, K8s/OpenShift.Jose Castillo LemaCode the Dream Skill-IT workshops2024-02-03T00:00:00-06:002024-02-03T14:00:58-06:00https://josecastillolema.github.io/codethedream<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=codethedream&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="130" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=codethedream&type=star&count=true&size=large" frameborder="0" scrolling="0" width="115" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=codethedream&type=fork&count=true&size=large" frameborder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
<h1 id="code-the-dream">Code the dream</h1>
<p><img src="https://raw.githubusercontent.com/josecastillolema/codethedream/main/img/logo.png" alt="Code the Dream" /></p>
<p>Classes for <a href="https://codethedream.org/">Code the Dream</a> Skill-IT workshops.</p>
<ul>
<li><a href="https://github.com/josecastillolema/codethedream/blob/main/lab01-docker.md">Docker Hands-on Practice</a></li>
</ul>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&type=follow&count=true&size=large" frameborder="0" scrolling="0" width="230" height="30" title="GitHub"></iframe>Jose Castillo LemaFlatpak SDK Extension for OCaml2024-01-04T00:00:00-06:002024-01-04T14:00:58-06:00https://josecastillolema.github.io/org-freedesktop-sdk-ext-ocaml<iframe src="https://ghbtns.com/github-btn.html?user=flathub&repo=org.freedesktop.Sdk.Extension.ocaml&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="130" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=flathub&repo=org.freedesktop.Sdk.Extension.ocaml&type=star&count=true&size=large" frameborder="0" scrolling="0" width="115" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=flathub&repo=org.freedesktop.Sdk.Extension.ocaml&type=fork&count=true&size=large" frameborder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
<h1 id="sdk-extension-for-ocaml-stable">SDK Extension for OCaml stable</h1>
<p>This extension contains various components of the <a href="https://ocaml.org/">OCaml</a> stable toolchain.</p>
<p>Includes the <a href="https://dune.build/">Dune build system</a> and the OCaml Package Manager <a href="https://opam.ocaml.org/">opam</a>.</p>
<h2 id="create-flatpak-ocaml-applications">Create Flatpak OCaml applications</h2>
<p>Several examples on how to Flatpak OCaml applications leveraging this SDK can be found <a href="https://github.com/josecastillolema/flatpak-ocaml-examples">here</a>.</p>
<h2 id="debugging">Debugging</h2>
<p>In order to use this extension in a Flatpak SDK environment you may add all provided tools in your PATH by executing first:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ source /usr/lib/sdk/ocaml/enable.sh
</code></pre></div></div>
<h2 id="install-packages-interactivelly">Install packages interactivelly</h2>
<p>In order to interactivelly install <a href="https://opam.ocaml.org/">OCaml Package Manager (opam)</a> packages in a Flatpak environmment you will need to inicialize a new environment:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ opam init --disable-sandboxing --no-setup --root $XDG_DATA_HOME/ocaml
$ eval $(opam env --root=$XDG_DATA_HOME/ocaml --switch=default --set-root --set-switch)
$ opam switch
# switch compiler description
→ default ocaml.5.1.0 default
</code></pre></div></div>
<h2 id="development">Development</h2>
<p>To use the SDK with your favourite editor:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo flatpak override --env=FLATPAK_ENABLE_SDK_EXT=ocaml com.visualstudio.code
$ sudo flatpak override --env=FLATPAK_ENABLE_SDK_EXT=ocaml org.gnu.emacs
$ sudo flatpak override --env=FLATPAK_ENABLE_SDK_EXT=ocaml io.neovim.nvim
</code></pre></div></div>
<p>or just use <code class="language-plaintext highlighter-rouge">FLATPAK_ENABLE_SDK_EXT=*</code> to load every SDK available in your system:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo flatpak override --env=FLATPAK_ENABLE_SDK_EXT=* com.visualstudio.code
</code></pre></div></div>
<p>When running your editor you should see something like this, i.e.:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak run com.visualstudio.code
flatpak-vscode: Enabling SDK extension "ocaml"
</code></pre></div></div>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&type=follow&count=true&size=large" frameborder="0" scrolling="0" width="230" height="30" title="GitHub"></iframe>Jose Castillo LemaHappy new year!2024-01-01T00:00:00-06:002024-01-01T14:00:58-06:00https://josecastillolema.github.io/newyear24<p><img src="/assets/images/posts/2024-01-01-newyear24/1.png" alt="" /></p>
<p><img src="/assets/images/posts/2024-01-01-newyear24/2.png" alt="" /></p>
<p><img src="/assets/images/posts/2024-01-01-newyear24/3.png" alt="" /></p>Jose Castillo LemaHow to Flatpak OCaml applications2023-12-19T00:00:00-06:002023-12-19T14:00:58-06:00https://josecastillolema.github.io/flatpak-ocaml<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=flatpak-ocaml-examples&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="130" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=flatpak-ocaml-examples&type=star&count=true&size=large" frameborder="0" scrolling="0" width="115" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=flatpak-ocaml-examples&type=fork&count=true&size=large" frameborder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
<h1 id="how-to-flatpak-an-ocaml-application">How to Flatpak an OCaml application</h1>
<p>Let’s take a couple <a href="https://ocaml.org/">OCaml</a> applications to illustrate <a href="https://flatpak.org/">Flatpak</a> distributing and packaging leveraging the <a href="https://github.com/flathub/org.freedesktop.Sdk.Extension.ocaml">Flatpak SDK Extension for OCaml</a>:</p>
<ul>
<li>a hello world CLI application</li>
<li>a simple GTK program from the <a href="https://v2.ocaml.org/learn/tutorials/introduction_to_gtk.html">Introduction to Gtk</a> OCaml tutorial</li>
</ul>
<p>The SDK is only needed during the building phase.</p>
<p><strong>Table of contents</strong></p>
<ul>
<li><a href="#how-to-flatpak-an-ocaml-application">How to Flatpak an OCaml application</a>
<ul>
<li><a href="#creating-a-hello-world-cli-application">Creating a hello world CLI application</a>
<ul>
<li><a href="#flatpak-manifest">Flatpak manifest</a></li>
<li><a href="#install-and-run-the-application">Install and run the application</a></li>
</ul>
</li>
<li><a href="#creating-a-simple-gtk-program">Creating a simple GTK program</a>
<ul>
<li><a href="#preparations">Preparations</a>
<ul>
<li><a href="#import-gtk2-library">Import GTK2 library</a></li>
<li><a href="#wrapper-script">Wrapper script</a></li>
</ul>
</li>
<li><a href="#building-from-sources">Building from sources</a>
<ul>
<li><a href="#flatpak-manifest-1">Flatpak manifest</a></li>
<li><a href="#install-and-run-the-application-1">Install and run the application</a></li>
</ul>
</li>
<li><a href="#building-with-opam">Building with opam</a>
<ul>
<li><a href="#source-files">Source files</a></li>
<li><a href="#generate-flatpak-manifest-code">Generate Flatpak manifest code</a></li>
<li><a href="#flatpak-manifest-2">Flatpak manifest</a></li>
<li><a href="#install-and-run-the-application-2">Install and run the application</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#publish-the-application">Publish the application</a></li>
</ul>
</li>
</ul>
<h2 id="creating-a-hello-world-cli-application">Creating a hello world CLI application</h2>
<p>Create a hello world <code class="language-plaintext highlighter-rouge">example.ml</code>:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="bp">()</span> <span class="o">=</span> <span class="n">print_endline</span> <span class="s2">"hello world"</span>
</code></pre></div></div>
<p>You can compile your code with the OCaml compiler <code class="language-plaintext highlighter-rouge">ocamlopt</code> (no need to do so at this point):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ocamlopt -o example example.ml
$ ./example
hello world
</code></pre></div></div>
<h3 id="flatpak-manifest">Flatpak manifest</h3>
<p>Some things to note in the following manifest:</p>
<ul>
<li>The SDK extension pointing to the <a href="https://github.com/flathub/org.freedesktop.Sdk.Extension.ocaml">Flatpak SDK Extension for OCaml</a> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.example.yaml#L9-L10">↵</a></li>
<li>The build options setting the <code class="language-plaintext highlighter-rouge">PATH</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.example.yaml#L13-L14">↵</a></li>
<li>Build some pre-requisistes using <code class="language-plaintext highlighter-rouge">dune</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.example.yaml#L17-L24">↵</a></li>
<li>Installing the application to <code class="language-plaintext highlighter-rouge">/app/bin</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.example.yaml#L33">↵</a></li>
</ul>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">app-id</span><span class="pi">:</span> <span class="s">flatpak.ocaml.example</span>
<span class="na">runtime</span><span class="pi">:</span> <span class="s">org.freedesktop.Sdk</span>
<span class="na">runtime-version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">22.08'</span>
<span class="na">sdk</span><span class="pi">:</span> <span class="s">org.freedesktop.Sdk</span>
<span class="na">sdk-extensions</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">org.freedesktop.Sdk.Extension.ocaml</span>
<span class="na">command</span><span class="pi">:</span> <span class="s">example</span>
<span class="na">build-options</span><span class="pi">:</span>
<span class="na">append-path</span><span class="pi">:</span> <span class="s">/usr/lib/sdk/ocaml/bin</span>
<span class="na">modules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">camlp-streams</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">git</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/camlp-streams</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">trunk</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">dune build</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">example</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">file</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">example.ml</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">ocamlopt -o example example.ml</span>
<span class="pi">-</span> <span class="s">install -Dm755 example -t /app/bin/</span>
</code></pre></div></div>
<h3 id="install-and-run-the-application">Install and run the application</h3>
<p>Build and install the Flatpak package locally using <code class="language-plaintext highlighter-rouge">flatpak-builder</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak-builder --force-clean build-dir flatpak.ocaml.example.yaml
$ flatpak-builder --user --install --force-clean build-dir flatpak.ocaml.example.yaml
</code></pre></div></div>
<p>Run the application:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak run flatpak.ocaml.example
hello world
</code></pre></div></div>
<p>The application has an installed size of 369.2 kB:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak info flatpak.ocaml.example
ID: flatpak.ocaml.example
Ref: app/flatpak.ocaml.example/x86_64/master
Arch: x86_64
Branch: master
Origin: example-origin
Collection:
Installation: user
Installed: 368.3 kB
Runtime: org.freedesktop.Sdk/x86_64/22.08
Sdk: org.freedesktop.Sdk/x86_64/22.08
Commit: 02386f983e23b6d991651e86c1b1a55531fd4fa6504c730c938bc06033c19f40
Subject: Export flatpak.ocaml.example
Date: 2023-10-09 12:34:32 +0000
</code></pre></div></div>
<h2 id="creating-a-simple-gtk-program">Creating a simple GTK program</h2>
<p>Let’s use the simple <code class="language-plaintext highlighter-rouge">lablgtk</code> program from the <a href="https://v2.ocaml.org/learn/tutorials/introduction_to_gtk.html">Introduction to Gtk</a> OCaml tutorial <code class="language-plaintext highlighter-rouge">simple.ml</code>:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">open</span> <span class="nc">GMain</span>
<span class="k">open</span> <span class="nc">GdkKeysyms</span>
<span class="k">let</span> <span class="n">locale</span> <span class="o">=</span> <span class="nn">GtkMain</span><span class="p">.</span><span class="nn">Main</span><span class="p">.</span><span class="n">init</span> <span class="bp">()</span>
<span class="k">let</span> <span class="n">main</span> <span class="bp">()</span> <span class="o">=</span>
<span class="k">let</span> <span class="n">window</span> <span class="o">=</span> <span class="nn">GWindow</span><span class="p">.</span><span class="n">window</span> <span class="o">~</span><span class="n">width</span><span class="o">:</span><span class="mi">320</span> <span class="o">~</span><span class="n">height</span><span class="o">:</span><span class="mi">240</span>
<span class="o">~</span><span class="n">title</span><span class="o">:</span><span class="s2">"Simple lablgtk program"</span> <span class="bp">()</span> <span class="k">in</span>
<span class="k">let</span> <span class="n">vbox</span> <span class="o">=</span> <span class="nn">GPack</span><span class="p">.</span><span class="n">vbox</span> <span class="o">~</span><span class="n">packing</span><span class="o">:</span><span class="n">window</span><span class="o">#</span><span class="n">add</span> <span class="bp">()</span> <span class="k">in</span>
<span class="n">window</span><span class="o">#</span><span class="n">connect</span><span class="o">#</span><span class="n">destroy</span> <span class="o">~</span><span class="n">callback</span><span class="o">:</span><span class="nn">Main</span><span class="p">.</span><span class="n">quit</span><span class="p">;</span>
<span class="c">(* Menu bar *)</span>
<span class="k">let</span> <span class="n">menubar</span> <span class="o">=</span> <span class="nn">GMenu</span><span class="p">.</span><span class="n">menu_bar</span> <span class="o">~</span><span class="n">packing</span><span class="o">:</span><span class="n">vbox</span><span class="o">#</span><span class="n">pack</span> <span class="bp">()</span> <span class="k">in</span>
<span class="k">let</span> <span class="n">factory</span> <span class="o">=</span> <span class="k">new</span> <span class="nn">GMenu</span><span class="p">.</span><span class="n">factory</span> <span class="n">menubar</span> <span class="k">in</span>
<span class="k">let</span> <span class="n">accel_group</span> <span class="o">=</span> <span class="n">factory</span><span class="o">#</span><span class="n">accel_group</span> <span class="k">in</span>
<span class="k">let</span> <span class="n">file_menu</span> <span class="o">=</span> <span class="n">factory</span><span class="o">#</span><span class="n">add_submenu</span> <span class="s2">"File"</span> <span class="k">in</span>
<span class="c">(* File menu *)</span>
<span class="k">let</span> <span class="n">factory</span> <span class="o">=</span> <span class="k">new</span> <span class="nn">GMenu</span><span class="p">.</span><span class="n">factory</span> <span class="n">file_menu</span> <span class="o">~</span><span class="n">accel_group</span> <span class="k">in</span>
<span class="n">factory</span><span class="o">#</span><span class="n">add_item</span> <span class="s2">"Quit"</span> <span class="o">~</span><span class="n">key</span><span class="o">:_</span><span class="nc">Q</span> <span class="o">~</span><span class="n">callback</span><span class="o">:</span> <span class="nn">Main</span><span class="p">.</span><span class="n">quit</span><span class="p">;</span>
<span class="c">(* Button *)</span>
<span class="k">let</span> <span class="n">button</span> <span class="o">=</span> <span class="nn">GButton</span><span class="p">.</span><span class="n">button</span> <span class="o">~</span><span class="n">label</span><span class="o">:</span><span class="s2">"Push me!"</span>
<span class="o">~</span><span class="n">packing</span><span class="o">:</span><span class="n">vbox</span><span class="o">#</span><span class="n">add</span> <span class="bp">()</span> <span class="k">in</span>
<span class="n">button</span><span class="o">#</span><span class="n">connect</span><span class="o">#</span><span class="n">clicked</span> <span class="o">~</span><span class="n">callback</span><span class="o">:</span> <span class="p">(</span><span class="k">fun</span> <span class="bp">()</span> <span class="o">-></span> <span class="n">prerr_endline</span> <span class="s2">"Ouch!"</span><span class="p">);</span>
<span class="c">(* Display the windows and enter Gtk+ main loop *)</span>
<span class="n">window</span><span class="o">#</span><span class="n">add_accel_group</span> <span class="n">accel_group</span><span class="p">;</span>
<span class="n">window</span><span class="o">#</span><span class="n">show</span> <span class="bp">()</span><span class="p">;</span>
<span class="nn">Main</span><span class="p">.</span><span class="n">main</span> <span class="bp">()</span>
<span class="k">let</span> <span class="bp">()</span> <span class="o">=</span> <span class="n">main</span> <span class="bp">()</span>
</code></pre></div></div>
<p>You can install the dependencies and compile your code (no need to do so at this point):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ opam install lablgtk
$ ocamlfind ocamlopt -package lablgtk2 -linkpkg simple.ml -o simple
$ ./simple
Ouch!
</code></pre></div></div>
<p>This is what you should see when you run it:</p>
<p><img src="https://raw.githubusercontent.com/josecastillolema/flatpak-ocaml-examples/main/img/simple.png" alt="" /></p>
<h3 id="preparations">Preparations</h3>
<h4 id="import-gtk2-library">Import GTK2 library</h4>
<p>We need the GTK2 library, let’s grab it from <a href="https://github.com/flathub/shared-modules">Flathub shared-modules repo</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git submodule add https://github.com/flathub/shared-modules.git
</code></pre></div></div>
<h4 id="wrapper-script">Wrapper script</h4>
<p><code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code> is empty by default when running Flatpak applications (<a href="https://github.com/flatpak/flatpak-builder/issues/474">flatpak/flatpak-builder#474</a>) so we will need a wrapper script <code class="language-plaintext highlighter-rouge">simple.sh</code> around the application:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>/app/lib
<span class="nb">exec</span> /app/bin/simple
</code></pre></div></div>
<h3 id="building-from-sources">Building from sources</h3>
<p><code class="language-plaintext highlighter-rouge">lablgtk</code> can be built from its <a href="https://github.com/garrigue/lablgtk/archive/refs/tags/2.18.13.tar.gz">sources</a>.</p>
<h4 id="flatpak-manifest-1">Flatpak manifest</h4>
<p>Some things to note in the following manifest:</p>
<ul>
<li>The SDK extension pointing to the <a href="https://github.com/flathub/org.freedesktop.Sdk.Extension.ocaml">Flatpak SDK Extension for OCaml</a> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L9-L10">↵</a></li>
<li>Permissions for the Flatpak app to access X11 (<code class="language-plaintext highlighter-rouge">--share=ipc</code> and <code class="language-plaintext highlighter-rouge">--socket=fallback-x11</code>) <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L12-L14">↵</a></li>
<li>The build options setting the <code class="language-plaintext highlighter-rouge">PATH</code> and some OCaml related environment variables <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L16-L19">↵</a></li>
<li>For some reason <code class="language-plaintext highlighter-rouge">debuginfo</code> was breaking <code class="language-plaintext highlighter-rouge">ocamlfind</code>, so it has been disabled <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L20">↵</a></li>
<li>We are importing GTK2 from the shared modules repository <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L23">↵</a></li>
<li>Installing some <code class="language-plaintext highlighter-rouge">lablgtk</code> pre-requisites: <code class="language-plaintext highlighter-rouge">ocamlfind</code> and <code class="language-plaintext highlighter-rouge">camlp-streams</code> (required only with OCaml>=5) <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L25-L49">↵</a></li>
<li><code class="language-plaintext highlighter-rouge">lablgtk</code> is build from its <a href="https://github.com/garrigue/lablgtk/archive/refs/tags/2.18.13.tar.gz">sources</a> instead of using opam <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L51-L60">↵</a></li>
<li>Installing the application to <code class="language-plaintext highlighter-rouge">/app/bin</code> and <code class="language-plaintext highlighter-rouge">lablgtk</code> library to <code class="language-plaintext highlighter-rouge">/app/lib</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L70-L71">↵</a></li>
<li>Removal of the build files at the post-install phase to limit the size of the resulting Flatpak application <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L72-L73">↵</a></li>
<li>Wrapper setup <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.build.yaml#L75-L81">↵</a></li>
</ul>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">app-id</span><span class="pi">:</span> <span class="s">flatpak.ocaml.lablgtk.build</span>
<span class="na">runtime</span><span class="pi">:</span> <span class="s">org.freedesktop.Sdk</span>
<span class="na">runtime-version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">22.08'</span>
<span class="na">sdk</span><span class="pi">:</span> <span class="s">org.freedesktop.Sdk</span>
<span class="na">sdk-extensions</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">org.freedesktop.Sdk.Extension.ocaml</span>
<span class="na">command</span><span class="pi">:</span> <span class="s">simple.sh</span>
<span class="na">finish-args</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">--share=ipc</span>
<span class="pi">-</span> <span class="s">--socket=fallback-x11</span>
<span class="na">build-options</span><span class="pi">:</span>
<span class="na">append-path</span><span class="pi">:</span> <span class="s">/usr/lib/sdk/ocaml/bin:/app/share/runtime/ocaml</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">CAML_LD_LIBRARY_PATH</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/lib:/usr/lib/sdk/ocaml/lib/ocaml:/usr/lib/sdk/ocaml/lib/ocaml/stublibs</span>
<span class="na">OCAMLFIND_CONF</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/findlib.conf</span>
<span class="na">no-debuginfo</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">modules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">shared-modules/gtk2/gtk2.json</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ocamlfind</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">git</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/ocamlfind</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">master</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">mkdir -p ${FLATPAK_DEST}/share/runtime/ocaml</span>
<span class="pi">-</span> <span class="s">./configure -bindir ${FLATPAK_DEST}/share/runtime/ocaml -config ${FLATPAK_DEST}/share/runtime/ocaml -no-topfind -sitelib ${FLATPAK_DEST}/share/runtime/ocaml/lib</span>
<span class="pi">-</span> <span class="s">make all</span>
<span class="pi">-</span> <span class="s">make install</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">ocamlfind printconf</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">camlp-streams</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">git</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/camlp-streams</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">trunk</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">dune build</span>
<span class="pi">-</span> <span class="s">dune install --prefix /app/share/runtime/ocaml</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">ocamlfind query camlp-streams</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">lablgtk</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">archive</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/garrigue/lablgtk/archive/refs/tags/2.18.13.tar.gz</span>
<span class="na">sha256</span><span class="pi">:</span> <span class="s">7b9e680452458fd351cf8622230d62c3078db528446384268cd0dc37be82143c</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">./configure</span>
<span class="pi">-</span> <span class="s">make world</span>
<span class="pi">-</span> <span class="s">make old-install DESTDIR=/app/share/runtime/ocaml</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">file</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">simple.ml</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">mv /app/share/runtime/ocaml/usr/lib/sdk/ocaml/lib/ocaml/lablgtk2 /app/share/runtime/ocaml/lib</span>
<span class="pi">-</span> <span class="s">ocamlfind ocamlopt -package lablgtk2 -linkpkg simple.ml -o simple</span>
<span class="pi">-</span> <span class="s">install -Dm755 simple -t /app/bin/</span>
<span class="pi">-</span> <span class="s">mv /app/share/runtime/ocaml/usr/lib/sdk/ocaml/lib/ocaml/stublibs/dlllablgtk2.so /app/lib</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">rm -rf /app/share/runtime/ocaml</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">simple-wrapper</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">file</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">simple.sh</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">cp simple.sh /app/bin</span>
</code></pre></div></div>
<h4 id="install-and-run-the-application-1">Install and run the application</h4>
<p>Build and install the Flatpak package locally using <code class="language-plaintext highlighter-rouge">flatpak-builder</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak-builder --force-clean build-dir flatpak.ocaml.lablgtk.build.yaml
$ flatpak-builder --user --install --force-clean build-dir flatpak.ocaml.lablgtk.build.yaml
</code></pre></div></div>
<p>Run the application:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak run flatpak.ocaml.lablgtk.build
Ouch!
</code></pre></div></div>
<p>This is what you should see when you run it:</p>
<p><img src="https://raw.githubusercontent.com/josecastillolema/flatpak-ocaml-examples/main/img/simple.png" alt="" /></p>
<p>The application has an installed size of 34.8 MB:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak info flatpak.ocaml.lablgtk.build
ID: flatpak.ocaml.lablgtk.build
Ref: app/flatpak.ocaml.lablgtk.build/x86_64/master
Arch: x86_64
Branch: master
Origin: build-origin
Collection:
Installation: user
Installed: 34.8 MB
Runtime: org.freedesktop.Sdk/x86_64/22.08
Sdk: org.freedesktop.Sdk/x86_64/22.08
Commit: 6acda68f932e9728d942e976b6d6b94cab2929eb4c91b087f58792028f18d536
Subject: Export flatpak.ocaml.lablgtk.build
Date: 2023-12-19 09:29:13 +0000
</code></pre></div></div>
<h3 id="building-with-opam">Building with opam</h3>
<h4 id="source-files">Source files</h4>
<p>We can leverage the <a href="https://opam.ocaml.org/">OCaml Package Manager (opam)</a> to install <code class="language-plaintext highlighter-rouge">lablgtk</code> into the Flatpak. For that, let’s leverage <a href="https://github.com/flatpak/flatpak-builder-tools">flatpak-builder-tools</a>, a collection of various scripts to aid in using <code class="language-plaintext highlighter-rouge">flatpak-builder</code> that among other things contains a <a href="https://github.com/flatpak/flatpak-builder-tools/tree/master/opam">helper tool</a> to automatically generate flatpak-builder source files from a <code class="language-plaintext highlighter-rouge">.json</code> generated by <code class="language-plaintext highlighter-rouge">opam tree</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git clone https://github.com/flatpak/flatpak-builder-tools
$ cd flatpak-builder-tools/opam
$ opam tree --json=lablgtk.json lablgtk
$ ./flatpak-opam-generator.py lablgtk.json > sources/lablgtk.json
</code></pre></div></div>
<p>The output sources file <code class="language-plaintext highlighter-rouge">sources/lablgtk.json</code> should look something like this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"file"</span><span class="p">,</span><span class="w">
</span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/garrigue/lablgtk/archive/2.18.13.tar.gz"</span><span class="p">,</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lablgtk.2.18.13"</span><span class="p">,</span><span class="w">
</span><span class="nl">"md5"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d0a326b99475216cc22232e72c89415f"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest"</span><span class="p">:</span><span class="w"> </span><span class="s2">"cache/md5/d0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest-filename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d0a326b99475216cc22232e72c89415f"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"file"</span><span class="p">,</span><span class="w">
</span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/ocaml/camlp-streams/archive/v5.0.1.tar.gz"</span><span class="p">,</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"camlp-streams.5.0.1"</span><span class="p">,</span><span class="w">
</span><span class="nl">"md5"</span><span class="p">:</span><span class="w"> </span><span class="s2">"afc874b25f7a1f13e8f5cfc1182b51a7"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest"</span><span class="p">:</span><span class="w"> </span><span class="s2">"cache/md5/af"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest-filename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"afc874b25f7a1f13e8f5cfc1182b51a7"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"file"</span><span class="p">,</span><span class="w">
</span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/ocaml/dune/releases/download/3.10.0/dune-3.10.0.tbz"</span><span class="p">,</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dune.3.10.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"sha256"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9ff03384a98a8df79852cc674f0b4738ba8aec17029b6e2eeb514f895e710355"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest"</span><span class="p">:</span><span class="w"> </span><span class="s2">"cache/sha256/9f"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest-filename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9ff03384a98a8df79852cc674f0b4738ba8aec17029b6e2eeb514f895e710355"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"file"</span><span class="p">,</span><span class="w">
</span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://download.camlcity.org/download/findlib-1.9.6.tar.gz"</span><span class="p">,</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ocamlfind.1.9.6"</span><span class="p">,</span><span class="w">
</span><span class="nl">"md5"</span><span class="p">:</span><span class="w"> </span><span class="s2">"96c6ee50a32cca9ca277321262dbec57"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest"</span><span class="p">:</span><span class="w"> </span><span class="s2">"cache/md5/96"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest-filename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"96c6ee50a32cca9ca277321262dbec57"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>
<h4 id="generate-flatpak-manifest-code">Generate Flatpak manifest code</h4>
<p>Let’s use the helper tool to generate the corresponding Flatpak manifest code:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">$ ./flatpak-opam-generator.py --generate lablgtk lablgtk.json</span>
<span class="nn">...</span>
<span class="c1"># Manifest code generated by flatpak-opam-generator</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">lablgtk</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">sources/lablgtk.json</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">git</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">master</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/opam-repository</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">ls -A --color=never | grep -Ev "cache|packages|repo" | xargs rm -rf</span>
<span class="pi">-</span> <span class="s">opam admin filter -y lablgtk.2.18.13 camlp-streams.5.0.1 dune.3.10.0 ocamlfind.1.9.6</span>
<span class="pi">-</span> <span class="s">opam admin cache</span>
<span class="pi">-</span> <span class="s">opam repo add lablgtk .</span>
<span class="pi">-</span> <span class="s">opam install -y lablgtk.2.18.13 camlp-streams.5.0.1 dune.3.10.0 ocamlfind.1.9.6</span>
<span class="pi">-</span> <span class="s">opam repo remove --all lablgtk</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">opam info --field name,all-installed-versions lablgtk</span>
</code></pre></div></div>
<h4 id="flatpak-manifest-2">Flatpak manifest</h4>
<p>Some things to note in the following manifest:</p>
<ul>
<li>The SDK extension pointing to the <a href="https://github.com/flathub/org.freedesktop.Sdk.Extension.ocaml">Flatpak SDK Extension for OCaml</a> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L9-L10">↵</a></li>
<li>Permissions for the Flatpak app to access X11 (<code class="language-plaintext highlighter-rouge">--share=ipc</code> and <code class="language-plaintext highlighter-rouge">--socket=fallback-x11</code>) <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L12-L14">↵</a></li>
<li>The build options setting the <code class="language-plaintext highlighter-rouge">PATH</code> and some OCaml related environment variables <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L15-L22">↵</a></li>
<li>We are importing GTK2 from the shared modules repository <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L25">↵</a></li>
<li>Creation of a new switch for installing <code class="language-plaintext highlighter-rouge">lablgtk</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L27-L44">↵</a></li>
<li>The manifest code generated by flatpak-opam-generator for <code class="language-plaintext highlighter-rouge">lablgtk</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L46-L62">↵</a></li>
<li>Installing the application to <code class="language-plaintext highlighter-rouge">/app/bin</code> and <code class="language-plaintext highlighter-rouge">lablgtk</code> library to <code class="language-plaintext highlighter-rouge">/app/lib</code> <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L71-L72">↵</a></li>
<li>Removal of the ocaml switch at the post-install phase to limit the size of the resulting Flatpak application <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L73-L74">↵</a></li>
<li>Wrapper setup <a href="https://github.com/josecastillolema/flatpak-ocaml-examples/blob/main/flatpak.ocaml.lablgtk.switch.yaml#L76-L82">↵</a></li>
</ul>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">app-id</span><span class="pi">:</span> <span class="s">flatpak.ocaml.lablgtk.switch</span>
<span class="na">runtime</span><span class="pi">:</span> <span class="s">org.freedesktop.Sdk</span>
<span class="na">runtime-version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">22.08'</span>
<span class="na">sdk</span><span class="pi">:</span> <span class="s">org.freedesktop.Sdk</span>
<span class="na">sdk-extensions</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">org.freedesktop.Sdk.Extension.ocaml</span>
<span class="na">command</span><span class="pi">:</span> <span class="s">simple.sh</span>
<span class="na">finish-args</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">--share=ipc</span>
<span class="pi">-</span> <span class="s">--socket=fallback-x11</span>
<span class="na">build-options</span><span class="pi">:</span>
<span class="na">append-path</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/bin:/app/share/runtime/ocaml/switch/_opam/bin:/usr/lib/sdk/ocaml/bin</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">CAML_LD_LIBRARY_PATH</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/switch/_opam/lib/stublibs:/app/share/runtime/ocaml/switch/_opam/lib/ocaml/stublibs:/app/share/runtime/ocaml/switch/_opam/lib/ocaml</span>
<span class="na">OCAML_TOPLEVEL_PATH</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/switch/_opam/lib/toplevel</span>
<span class="na">OPAMROOT</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml</span>
<span class="na">OPAMSWITCH</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/switch</span>
<span class="na">OPAM_SWITCH_PREFIX</span><span class="pi">:</span> <span class="s">/app/share/runtime/ocaml/switch/_opam</span>
<span class="na">modules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">shared-modules/gtk2/gtk2.json</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">switch</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">git</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">master</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/opam-repository</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">archive</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/ocaml/archive/refs/tags/5.1.0.tar.gz</span>
<span class="na">dest</span><span class="pi">:</span> <span class="s">switch</span>
<span class="na">sha256</span><span class="pi">:</span> <span class="s">43a3ac7aab7f8880f2bb6221317be55319b356e517622fdc28359fe943e6a450</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">mkdir -p ${FLATPAK_DEST}/share/runtime/ocaml</span>
<span class="pi">-</span> <span class="s">mv switch ${FLATPAK_DEST}/share/runtime/ocaml</span>
<span class="pi">-</span> <span class="s">opam init -y --bare --disable-sandboxing .</span>
<span class="pi">-</span> <span class="s">opam switch create -y --deps-only ${FLATPAK_DEST}/share/runtime/ocaml/switch</span>
<span class="pi">-</span> <span class="s">opam pin -y ${FLATPAK_DEST}/share/runtime/ocaml/switch</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">opam switch list</span>
<span class="c1"># Manifest code generated by flatpak-opam-generator</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">lablgtk</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">sources/lablgtk.json</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">git</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">master</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/ocaml/opam-repository</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">ls -A --color=never | grep -Ev "cache|packages|repo" | xargs rm -rf</span>
<span class="pi">-</span> <span class="s">opam admin filter -y lablgtk.2.18.13 camlp-streams.5.0.1 dune.3.10.0 ocamlfind.1.9.6</span>
<span class="pi">-</span> <span class="s">opam admin cache</span>
<span class="pi">-</span> <span class="s">opam repo add lablgtk .</span>
<span class="pi">-</span> <span class="s">opam install -y lablgtk.2.18.13 camlp-streams.5.0.1 dune.3.10.0 ocamlfind.1.9.6</span>
<span class="pi">-</span> <span class="s">opam repo remove --all lablgtk</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">opam info --field name,all-installed-versions lablgtk</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">file</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">simple.ml</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">ocamlfind ocamlopt -package lablgtk2 -linkpkg simple.ml -o simple</span>
<span class="pi">-</span> <span class="s">install -Dm755 simple -t /app/bin/</span>
<span class="pi">-</span> <span class="s">cp /app/share/runtime/ocaml/switch/_opam/lib/stublibs/dlllablgtk2.so /app/lib</span>
<span class="na">post-install</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">rm -rf /app/share/runtime/ocaml</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">simple-wrapper</span>
<span class="na">buildsystem</span><span class="pi">:</span> <span class="s">simple</span>
<span class="na">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">type</span><span class="pi">:</span> <span class="s">file</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">simple.sh</span>
<span class="na">build-commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">cp simple.sh /app/bin</span>
</code></pre></div></div>
<h4 id="install-and-run-the-application-2">Install and run the application</h4>
<p>Build and install the Flatpak package locally using <code class="language-plaintext highlighter-rouge">flatpak-builder</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak-builder --force-clean build-dir flatpak.ocaml.lablgtk.switch.yaml
$ flatpak-builder --user --install --force-clean build-dir flatpak.ocaml.lablgtk.switch.yaml
</code></pre></div></div>
<p>Run the application:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak run flatpak.ocaml.lablgtk.switch
Ouch!
</code></pre></div></div>
<p>This is what you should see when you run it:</p>
<p><img src="https://raw.githubusercontent.com/josecastillolema/flatpak-ocaml-examples/main/img/simple.png" alt="" /></p>
<p>The application has an installed size of 11.3 MB:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak info flatpak.ocaml.lablgtk.switch
ID: flatpak.ocaml.lablgtk.switch
Ref: app/flatpak.ocaml.lablgtk.switch/x86_64/master
Arch: x86_64
Branch: master
Origin: lablgtk-origin
Collection:
Installation: user
Installed: 11.3 MB
Runtime: org.freedesktop.Sdk/x86_64/22.08
Sdk: org.freedesktop.Sdk/x86_64/22.08
Commit: b3159cf05f2d89d7caaae3bc7bc6fd6a2ab70d5195374b4222a3cbedf8f635b0
Parent: 499a0892394a54c93976d422aa533563b6a1b1212fd9036fbc4fcbdd023f87dd
Subject: Export flatpak.ocaml.lablgtk.switch
Date: 2023-10-16 12:01:01 +0000
</code></pre></div></div>
<h2 id="publish-the-application">Publish the application</h2>
<p>Info on how to later publish the application on <a href="https://flathub.org/">Flathub</a> can be found <a href="https://docs.flathub.org/docs/for-app-authors/submission/">here</a>.</p>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&type=follow&count=true&size=large" frameborder="0" scrolling="0" width="230" height="30" title="GitHub"></iframe>Jose Castillo LemaPHYSICS 8th General Assembly2023-11-19T00:00:00-06:002023-11-19T14:00:58-06:00https://josecastillolema.github.io/physics-ga8<p><a href="/physics"><img src="/assets/images/posts/2022-09-20-physics-ga4/1.png" alt="" /></a></p>
<p>The <a href="/physics">PHYSICS project</a>, held its 8th General Assembly meeting on November 8th – 9th, 2023, in Florence, Italy. Hosted by GFT, the meeting provided an opportunity for partners to present updates on task progress and deliverables, as well as discuss upcoming project results. The coordinator and leaders of the work packages (WP) led discussions on any outstanding issues, fostering active participation and constructive feedback.</p>
<p>The meeting was conducted using a hybrid format, accommodating both in-person and remote attendees. Among the meeting’s key objectives were the status of PHYSICS’ 2nd Iteration Pilot Implementation, the finalization of the Final Review demo, and the definition of the Final Review agenda and logistics.</p>
<p><img src="/assets/images/posts/2023-11-19-physics-ga8.jpg" alt="" /></p>Jose Castillo Lemadiff.blog2023-10-29T00:00:00-05:002023-10-29T15:00:58-05:00https://josecastillolema.github.io/diff-blog<p><a href="https://diff.blog/"><img src="/assets/images/posts/2023-10-29-diff-blog/1.png" alt="" /></a></p>
<p><a href="https://diff.blog/">diff.blog</a> is a platform that helps you discover and follow amazing developer blogs. Whether your interests are in Python, Rust, AI, Distributed Systems or XYZ diff.blog has got amazing blogs for you to follow!</p>
<h3 id="how-is-it-different-from-medium">How is it different from Medium?</h3>
<p>Unlike Medium does not host any blogs, merely acts as a platform that makes it easier to discover and subscribe to blogs. So you own your own blog and content. You can host your blog in a Wordpress site, GitHub pages, Ghost, or wherever you want. This means even if diff.blog shut downs one day it won’t affect your blog at all.</p>
<h3 id="why-diffblog">Why diff.blog?</h3>
<p>There are a lot of amazing developer blogs in the Internet. But very few of them gets visibility. Because of this visibility issue a lot of the developers blogs are shutting down or is moving to Medium in search of views. Developers should be able to own their blog without having to compromise on the views. Blogs are probably the last remaining bits of Internet, a network that was supposed to be decentralized and not owned by a few companies. diff.blog’s mission is to bring the audience back to the blogs and make blogs popular again.</p>
<h3 id="how-does-it-work">How does it work?</h3>
<p>The underlying engine of diff.blog is similar to an RSS reader. All most all the blogs have RSS feed. RSS feeds makes it really easy to keep updated with the posts of a blog. No blockchain. Nothing fancy. It’s just a file. You can read more about RSS feeds at https://www.youneedfeeds.com/.</p>
<h3 id="profile">Profile</h3>
<p><a href="https://diff.blog/josecastillolema/">https://diff.blog/josecastillolema/</a>
<a href="https://diff.blog/josecastillolema/"><img src="/assets/images/posts/2023-10-29-diff-blog/2.png" alt="" /></a></p>Jose Castillo LemaDevelopment workflows on inmutable distros: rootless setup2023-10-21T00:00:00-05:002023-10-21T15:00:58-05:00https://josecastillolema.github.io/dev-inmutable-distros<blockquote>
<p>Continuation of <a href="https://samsai.eu/">Samsai</a> notes on <a href="https://samsai.eu/post/toolbox-based-emacs-flatpak-workflow/">Toolbox-based Emacs Flatpak workflow</a>.</p>
</blockquote>
<p>I have been using inmutable OS distributions for a while (Fedora Silverblue and Sericea, see my <a href="/dotfiles">dotfiles</a>). They have the following characteristics:</p>
<ul>
<li>System root (baseOS) is mostly immutable</li>
<li>System software installation/updates are handled as images and applied on reboot</li>
<li>For installing desktop applications, <a href="https://flatpak.org/">Flatpak</a> is the recommended default route</li>
<li><a href="https://containertoolbx.org/">Toolbx</a> can be used to set up containerized Linux environments for developer tools, these containers will mount your home directory and certain important files for GUI programs to work as well</li>
<li>Local user (rootless) installations</li>
</ul>
<p>I personally follow these guidelines when installing new applications:</p>
<ul>
<li>If it is a desktop application, prefer Flatpak (and some terminal ones too, i.e.: <a href="https://flathub.org/apps/io.neovim.nvim">Neovim</a> and <a href="https://flathub.org/apps/org.gnu.emacs">Emacs</a>)</li>
<li>For terminal applications, consider Toolbx or local installations</li>
<li>Do not install desktop applications into Toolbx</li>
<li>Avoid duplication (i.e.: installing the same editors or development environments in several places)</li>
<li>Try to avoid <code class="language-plaintext highlighter-rouge">rpm-ostree</code> layering on baseOS as much as possible</li>
</ul>
<p>The development workflow story on inmutable distros hasn’t really been standardized yet, as these distros are quite new. Let’s take a look at several approaches and <strong>finally discuss the local (rootless) installation method</strong>.</p>
<h2 id="layering-with-rpm-ostree-not-a-good-idea">Layering with rpm-ostree (not a good idea)</h2>
<p>You can also install development tools directly on the inmutable distros install using package layering with <code class="language-plaintext highlighter-rouge">rpm-ostree</code>. So, if you want to, you can install your editor, compilers, build tools and linters straight on the Silverblue install.</p>
<p>However, this isn’t really how most people view you should use Silverblue. The application installation process is a bit more annoying, although experimental support for installing software without rebooting does exist nowadays. It also makes your system install kind of messy due to large numbers of overlayed packages.</p>
<p>I wouldn’t take this route because while you aren’t strictly speaking losing all of the benefits of inmutable distros, you are making life quite difficult for yourself compared to just using regular Fedora Workstation for instance. You also don’t get the benefits of separating your system from your application environments and expose yourself to more potential breakages.</p>
<h2 id="toolbx-approaches">Toolbx approaches</h2>
<h3 id="single-toolbx-container-for-all-dev-activities">Single toolbx container for all dev activities</h3>
<p>The easiest way to have everything working in a predictable and simple manner is to create a single Toolbox container, which has all of the development tools for every single project installed within it. This means that the container contains your text editor of choice, compilers, linters, build tools and all of their dependencies.</p>
<p>The benefit of this approach is that it is extremely close to how you’d work on any other Linux distribution.</p>
<p>This approach has several drawbacks:</p>
<ul>
<li>All software pilled into one environment</li>
<li>Keeping the text editor inside the Toolbox still results in somewhat poor integration with the host system</li>
<li>Install desktop applications into toolbx containers instead of Flatpak applications</li>
</ul>
<h3 id="a-toolbx-container-per-language--project">A toolbx container per language / project</h3>
<p>Another (better IMO) possibility is to separately set up a Toolbox container for each project you work on. This means that all of your project environments are fully separated from each other and all of them only carry tools and dependencies relevant to the project in question.</p>
<p>Loss of a Toolbox container limits the damage to a particular project and per-project Toolboxes are fairly simple to recreate.</p>
<p>Drawbacks:</p>
<ul>
<li>Certain parts of your development workflow need to be duplicated. You potentially need to install your text editor and all of its required dependencies and tools in each environment.</li>
<li>Keeping the text editor inside the Toolbox still results in somewhat poor integration with the host system.</li>
</ul>
<h2 id="flatpak-approach">Flatpak approach</h2>
<p>You can install Flatpak SDKs such as the Rust build tools like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak install org.freedesktop.Sdk.Extension.rust-stable
</code></pre></div></div>
<p>And then load them into a Flatpak editor using an SDK extension flag:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ FLATPAK_ENABLE_SDK_EXT=rust-stable flatpak run com.visualstudio.code
</code></pre></div></div>
<p>or just load every SDK available in your local setup:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ FLATPAK_ENABLE_SDK_EXT=* flatpak run com.visualstudio.code
</code></pre></div></div>
<p>This causes the tools and libraries from that SDK to be made visible to the Flatpak application. There are Flatpak SDKs for a few languages like Java, Rust, Haskell, PHP and Node, but obviously support for all use-cases does not exist. But if you only plan to develop in languages that already have an SDK ready or are willing to learn how to package more SDKs, then this approach is definitely viable for things like Neovim, Emacs and VSCode Flatpaks.</p>
<p>Drawbacks:</p>
<ul>
<li>Some languages do not have an SDK available</li>
<li>Limited to the language runtime versions available in the SDKs</li>
<li>Duplication of the language runtime (plus you will need to install all the library dependencies on the Flatpak to have proper code support from your editor)</li>
</ul>
<h2 id="combined-approach">Combined approach</h2>
<p>You can also mix approaches such that part of the development activity happens outside Toolbox and part of it inside the Toolbox. The simplest case would be installing your text editor via Flatpak for example and then connecting from that text editor to a Toolbox for project-specific tools like compilers.</p>
<p>The benefit here is that you can install tools where they make most sense and where they integrate the best. So, you will get your nice app launchers and the ability to keep project environments separate.</p>
<p>Tools available:</p>
<ul>
<li>For VSCode
<ul>
<li><a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers">Dev Containers extension</a></li>
<li><a href="https://github.com/owtaylor/toolbox-vscode">toolbox-vscode</a>: a script that configures the current toolbox container to work with the Remote Containers Visual Studio Code extension</li>
</ul>
</li>
<li>For Emacs
<ul>
<li><a href="https://github.com/fejfighter/toolbox-tramp">toolbox-tramp</a></li>
</ul>
</li>
<li>For Neovim
<ul>
<li><code class="language-plaintext highlighter-rouge">nvim --remote</code> ?</li>
<li><a href="https://github.com/jamestthompson3/nvim-remote-containers">nvim-remote-containers</a></li>
</ul>
</li>
</ul>
<h2 id="user-rootless-installations">User (rootless) installations</h2>
<p>I have not seen much information about this method anywhere and for me as of today it is the prefered approach. Flatpak applications (i.e.: editors) cannot access the root filesystem (i.e.: the preinstalled python package on <code class="language-plaintext highlighter-rouge">/usr/bin/python</code>). However they have full access to the home directory (same as Toolbx containers).</p>
<p>So installing the development runtimes and tools locally (and then configuring your Flatpak editor to use them) provides an excelent out of the box developer experience without the need of Flatpak SDKs nor plugins to enable your editor to access the Toolbx containers.</p>
<p>Drawbacks:</p>
<ul>
<li>It can be more time consuming to set up than normal <code class="language-plaintext highlighter-rouge">rpm</code> installs in some scenarios</li>
<li>No automatic updates</li>
</ul>
<p>Let’s take a look at local installs for several platforms.</p>
<h3 id="ocaml">OCaml</h3>
<p>We will leverage the <a href="https://opam.ocaml.org/">OCaml Package Manager (opam)</a> to install the platform (or several versions) and local switches to each project:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ curl https://github.com/ocaml/opam/releases/download/2.1.5/opam-2.1.5-i686-linux -Lo ~/bin/opam && chmod +x ~/bin/opam
</code></pre></div></div>
<p>From a toolbx container with proper development tools, i.e.: <a href="https://github.com/josecastillolema/toolbox-images/blob/main/fedora-toolbox-38/Containerfile">this one</a> incialize the opam environment and install the <a href="https://ocaml.org/docs/platform">platform tools</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>⬢ $ opam init
⬢ $ opam install dune ocaml-lsp-server odoc ocamlformat utop
</code></pre></div></div>
<p>Optionally, install some extras for Emacs, Vim and Neovim:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>⬢ $ opam install ocp-indent ocp-index merlin tuareg
</code></pre></div></div>
<p>We need to add the opam path (<code class="language-plaintext highlighter-rouge">~/bin</code>) to our editor of choice (i.e.: VSCode) path:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo flatpak override --env=PATH='/app/bin:/usr/bin:/home/$USER/bin:/home/$USER/.opam/default/bin' com.visualstudio.code
</code></pre></div></div>
<p>Finally, open the project in VSCode and choose the corresponding opam switch.</p>
<h4 id="using-local-switches">Using local switches</h4>
<p>It is possible to define a switch within the source of a project to be used specifically in that project.
If a <strong>local switch</strong> is detected in the current directory or a parent, opam will select it automatically.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>⬢ $ opam switch create .
</code></pre></div></div>
<p>Finally, open the project in VSCode and choose the corresponding recommended opam switch.</p>
<h3 id="golang">Golang</h3>
<p>Download latest version:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mkdr ~/go
$ curl https://go.dev/dl/go1.21.3.linux-amd64.tar.gz -Lo ~/go.tar.gz
$ tar xf ~/go/go.tar.gz
$ mv ~/go/go ~/go/go-1.21.3
</code></pre></div></div>
<p>Add the following environment variables to your environment:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export GOROOT=$HOME/go/go-1.21.3
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
</code></pre></div></div>
<p>Check installation:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ go version
go version go1.21.3 linux/amd64
</code></pre></div></div>
<p>Finally, open VSCode (it should automatically detect the local Golang installation), install the <a href="https://marketplace.visualstudio.com/items?itemName=golang.Go">Go VSCode extension</a> and click on <code class="language-plaintext highlighter-rouge">⚠ Analysis Tools Missing</code> to install those.</p>
<p><img src="/assets/images/posts/2023-10-21-dev-inmutable-distros/go.png" alt="" /></p>
<h3 id="python">Python</h3>
<h4 id="local-install">Local install</h4>
<p>Install both <code class="language-plaintext highlighter-rouge">python</code> and <code class="language-plaintext highlighter-rouge">pip</code> in the local user environment.</p>
<p>From a toolbx container with proper development tools, i.e.: <a href="https://github.com/josecastillolema/toolbox-images/blob/main/fedora-toolbox-38/Containerfile">this one</a> download and compile Python:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>⬢ $ wget https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tgz
⬢ $ tar -xf Python-3.?.?.tar.xz
⬢ $ cd Python-3.?.?.tar.xz
⬢ $ ./configure --prefix=$HOME
⬢ $ make install
⬢ $ ln -s ~/bin/python3 ~/bin/python
⬢ $ pip install readline
</code></pre></div></div>
<p>Then you can just pip install any dependencies, open the project in VSCode and choose the corresponding Python environment <code class="language-plaintext highlighter-rouge">~/bin/python</code>. I do not tend to pip install the requirements of the projects thought (only the indispensable ones, like i.e.: ansible), instead prefer the virtual environments approach that will be described next.</p>
<p><img src="/assets/images/posts/2023-10-21-dev-inmutable-distros/python.png" alt="" /></p>
<h4 id="using-python-virtual-environments">Using python virtual environments</h4>
<p>Before opening the project in VSCode:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ flatpak run --command=sh com.visualstudio.code
[📦] python -m venv .
[📦] source bin/activate
()[📦] pip install -r requirements.txt
</code></pre></div></div>
<p>Then open the project in VSCode and choose the local virtual environment.</p>
<h3 id="ansible">Ansible</h3>
<p>Python local install is a pre-requisite.</p>
<p>Local ansible installation:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python -m pip install --user ansible ansible-lint
</code></pre></div></div>
<p>Ansible will be installed on ~/.local/bin, so we need to add this path to our editor of choice (i.e.: VSCode):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ which ansible
~/.local/bin/ansible
$ sudo flatpak override --env=PATH='/app/bin:/usr/bin:/home/$USER/.local/bin' com.visualstudio.code
</code></pre></div></div>
<p>Installed the Ansible extension by Red Hat in VSCode and <a href="https://developers.redhat.com/articles/2023/08/22/enhance-ansible-development-experience-lightspeed">enabled Lightspeed</a>.</p>
<p>When opening VSCode it should automatically detect the local Ansible installation.</p>Jose Castillo LemaContinuation of Samsai notes on Toolbox-based Emacs Flatpak workflow.Kubemark on OpenShift2023-09-19T00:00:00-05:002023-09-19T15:00:58-05:00https://josecastillolema.github.io/kubemark-ocp<p><a href="https://github.com/kubernetes/kubernetes/tree/master/cmd/kubemark">Kubemark</a> is a performance testing tool which allows users to run experiments on simulated clusters, by creating “hollow” Kubernetes nodes. What this means is that the nodes do not actually run containers or attach storage, but they do behave like they did, with updates to etcd and all the trimmings. At the same time, <strong>hollow nodes are extremely light (<30 MiB)</strong>.</p>
<p>The primary use case of Kubemark is scalability testing, as simulated clusters can be much bigger than the real ones. The objective is to expose problems with the master components (API server, controller manager or scheduler) that appear only on bigger clusters (e.g. small memory leaks).</p>
<h2 id="hands-to-work">Hands to work</h2>
<p>We won’t be using the <a href="https://github.com/kubernetes-sigs/cluster-api-provider-kubemark/">Cluster API Kubemark Provider</a> for this demo, and instead we will be using directly Kubemark itself.</p>
<p>Let’s assume we have a <strong>working OpenShift cluster</strong> available. We will be leveraging a <a href="https://developers.redhat.com/products/openshift-local/overview">Red Hat OpenShift Local instance</a> (formerly Red Hat CodeReady Containers) for this demo:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ oc version
Client Version: 4.13.6
Kustomize Version: v4.5.7
Server Version: 4.13.6
Kubernetes Version: v1.26.6+73ac561
❯ oc get node
NAME STATUS ROLES AGE VERSION
crc-2zx29-master-0 Ready control-plane,master,worker 54d v1.26.6+73ac561
</code></pre></div></div>
<p>Let’s create a new <strong>project</strong>, <strong>secret</strong> and corresponding <strong>permissions</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ oc new-project kubemark
Now using project "kubemark" on server "https://api.crc.testing:6443".
❯ oc create secret generic kubeconfig --from-file=kubeconfig=$KUBECONFIG
secret/kubeconfig created
❯ oc adm policy add-scc-to-user privileged -z default
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added: "default"
</code></pre></div></div>
<p>Let’s create the <strong>Kubemark pod</strong> (which in turn will automatically instantiate a new node):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">❯ cat <<EOF | oc apply -f -</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">hollow-node</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">kubemark-node</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">kubemark</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">args</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">--v=3</span>
<span class="pi">-</span> <span class="s">--morph=kubelet</span>
<span class="pi">-</span> <span class="s">--name=kubemark-node</span>
<span class="pi">-</span> <span class="s">--extended-resources=cpu=1,memory=4G</span>
<span class="na">command</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">/kubemark</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">quay.io/cluster-api-provider-kubemark/kubemark:v1.26.7</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">hollow-node</span>
<span class="na">securityContext</span><span class="pi">:</span>
<span class="na">privileged</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">volumeMounts</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">mountPath</span><span class="pi">:</span> <span class="s">/kubeconfig</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">kubeconfig</span>
<span class="pi">-</span> <span class="na">mountPath</span><span class="pi">:</span> <span class="s">/run/containerd/containerd.sock</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">containerd-sock</span>
<span class="na">volumes</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">kubeconfig</span>
<span class="na">secret</span><span class="pi">:</span>
<span class="na">defaultMode</span><span class="pi">:</span> <span class="m">420</span>
<span class="na">secretName</span><span class="pi">:</span> <span class="s">kubeconfig</span>
<span class="pi">-</span> <span class="na">hostPath</span><span class="pi">:</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">/run/crio/crio.sock</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">Socket</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">containerd-sock</span>
<span class="s">EOF</span>
<span class="s">pod/kubemark-node created</span>
</code></pre></div></div>
<h2 id="validation">Validation</h2>
<p>Let’s check the if new node was properly registered:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ oc get po
NAME READY STATUS RESTARTS AGE
kubemark-node 1/1 Running 0 5s
❯ oc get node
NAME STATUS ROLES AGE VERSION
crc-2zx29-master-0 Ready control-plane,master,worker 54d v1.26.6+73ac561
kubemark-node Ready <none> 4s v1.26.7
</code></pre></div></div>
<p>The cluster should be healthy:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ oc get co
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE
authentication 4.13.6 True False False 12d
cluster-api 4.13.6 True False False 13d
config-operator 4.13.6 True False False 54d
console 4.13.6 True False False 12d
control-plane-machine-set 4.13.6 True False False 54d
dns 4.13.6 True False False 12d
etcd 4.13.6 True False False 54d
image-registry 4.13.6 True False False 12d
ingress 4.13.6 True False False 54d
kube-apiserver 4.13.6 True False False 54d
kube-controller-manager 4.13.6 True False False 54d
kube-scheduler 4.13.6 True False False 54d
kube-storage-version-migrator 4.13.6 True False False 12d
machine-api 4.13.6 True False False 54d
machine-approver 4.13.6 True False False 54d
machine-config 4.13.6 True False False 54d
marketplace 4.13.6 True False False 54d
network 4.13.6 True False False 54d
openshift-apiserver 4.13.6 True False False 12d
openshift-controller-manager 4.13.6 True False False 12d
openshift-samples 4.13.6 True False False 54d
operator-lifecycle-manager 4.13.6 True False False 54d
operator-lifecycle-manager-catalog 4.13.6 True False False 54d
operator-lifecycle-manager-packageserver 4.13.6 True False False 119m
platform-operators-aggregated 4.13.6 True False False 119m
service-ca 4.13.6 True False False 54d
</code></pre></div></div>
<p>And there should a few pods already “running” in the new hollow node:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ oc get pods -A --field-selector spec.nodeName=kubemark-node
NAMESPACE NAME READY STATUS RESTARTS AGE
hostpath-provisioner csi-hostpathplugin-8p9j5 4/4 Running 0 17m
openshift-dns dns-default-lt7g8 2/2 Running 0 17m
openshift-dns node-resolver-9plz7 1/1 Running 0 17m
openshift-image-registry node-ca-x7hq7 1/1 Running 0 17m
openshift-ingress-canary ingress-canary-l2mlx 1/1 Running 0 17m
openshift-machine-config-operator machine-config-daemon-smq5z 2/2 Running 0 17m
openshift-multus multus-7xp8p 1/1 Running 0 17m
openshift-multus multus-additional-cni-plugins-rv6j7 0/1 Init:0/6 0 17m
openshift-multus network-metrics-daemon-zh2vz 2/2 Running 0 17m
openshift-network-diagnostics network-check-target-l85xq 1/1 Running 0 17m
openshift-sdn sdn-rv9mb 2/2 Running 0 17m
</code></pre></div></div>
<p>Let’s try to create some pods on the new hollow node:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ oc run test --image nginx --overrides='{"spec": { "nodeSelector": {"kubernetes.io/hostname": "kubemark-node"}}}'
pod/test created
❯ oc get po -o wide test
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test 1/1 Running 0 36s 192.168.192.168 kubemark-node <none> <none>
</code></pre></div></div>
<h2 id="scale-out">Scale out</h2>
<p>Finally, bear in mind that in order to create new hollow nodes you will have to change two fields in the pod definition:</p>
<ul>
<li>The pod name: <code class="language-plaintext highlighter-rouge">metadata.name</code></li>
<li>The name of the hollow node: <code class="language-plaintext highlighter-rouge">spec.containers.args.--name</code></li>
</ul>Jose Castillo LemaKubemark is a performance testing tool which allows users to run experiments on simulated clusters, by creating “hollow” Kubernetes nodes. What this means is that the nodes do not actually run containers or attach storage, but they do behave like they did, with updates to etcd and all the trimmings. At the same time, hollow nodes are extremely light (<30 MiB).My Linux desktop2023-06-07T00:00:00-05:002023-06-07T15:00:58-05:00https://josecastillolema.github.io/dotfiles<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=dotfiles&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="130" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=dotfiles&type=star&count=true&size=large" frameborder="0" scrolling="0" width="115" height="30" title="GitHub"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&repo=dotfiles&type=fork&count=true&size=large" frameborder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
<h1 id="dotfiles">dotfiles</h1>
<p>My Linux desktop setup on <a href="https://fedoraproject.org/sericea/">Fedora Sericea</a>.</p>
<p><img src="https://raw.githubusercontent.com/josecastillolema/dotfiles/master/img/screenshot.png" alt="" /></p>
<h2 id="desktop">Desktop</h2>
<ul>
<li>
<p>Window manager: Sway via baseOS</p>
<p>Only use wayland applications; xwayland apps are not properly scaled <a href="https://github.com/swaywm/sway/issues/2966">swaywm/sway#2966</a>, drag and drop does not work <a href="https://github.com/swaywm/sway/issues/6460">swaywm/sway#6460</a> and have a glitched behaviour uppon minimized on system tray <a href="https://github.com/swaywm/sway/issues/6905">swaywm/sway#6905</a>.</p>
</li>
<li>Browser
<ul>
<li>Primary: Firefox via <a href="https://flathub.org/apps/org.mozilla.firefox">Flatpak</a></li>
<li>
<p>Secondary: Chrome via <a href="https://flathub.org/apps/com.google.Chrome">Flatpak</a></p>
<p>With flags <code class="language-plaintext highlighter-rouge">--ozone-platform-hint=wayland</code> and <code class="language-plaintext highlighter-rouge">--enable-pixel-canvas-recording=enabled</code>.</p>
</li>
</ul>
</li>
<li>
<p>Terminal: <a href="https://wezfurlong.org/wezterm/">WezTerm</a> via <a href="https://flathub.org/apps/org.wezfurlong.wezterm">Flatpak</a></p>
<p>Amazing terminal with wayland, grabbable scrollbar and ligature support.</p>
<p>Would prefer Foot but having a grabbable scrollbar is a must for now. One workaround would be to setup fast scroll (i.e.: <em>$mod + scroll wheel</em>) but I have not been able to configure it correctly (if anyone has please let me know <a href="#issues">↵</a>). Also Foot does not support ligatures <a href="https://codeberg.org/dnkl/foot/issues/57">dnkl/foot#57</a>.</p>
</li>
<li>IDE:
<ul>
<li>
<p>Primary: Visual Studio Code via <a href="https://flathub.org/apps/com.visualstudio.code">Flatpak</a></p>
<p>With flags <code class="language-plaintext highlighter-rouge">--socket=wayland</code> and <code class="language-plaintext highlighter-rouge">--ozone-platform-hint=wayland</code>.</p>
<p>With <a href="https://github.com/JetBrains/JetBrainsMono">JetBrains Mono font</a> with programming ligatures installed via rpm-ostree.</p>
<p>Instead of using SDK extensions <a href="https://josecastillolema.github.io/dev-inmutable-distros/">tend to opt for local language installs (golang, ocaml, etc.)</a>.</p>
<p><a href="https://github.com/owtaylor/toolbox-vscode">toolbox-vscode</a> to integrate VSCode and toolbx.</p>
</li>
<li>
<p>Secundary: Neovim via <a href="https://flathub.org/es/apps/io.neovim.nvim">Flatpak</a></p>
</li>
</ul>
</li>
<li>
<p>File manager: Nautilus via rpm-ostree with NautilusPreviewer (GNOME Sushi) via Flatpak (org.gnome.NautilusPreviewer)</p>
<p>Would prefer Thunar or PCMan FM but miss the preview feature.</p>
</li>
<li>
<p>Text editor: Gnome Text Editor via <a href="https://flathub.org/apps/org.gnome.TextEditor">Flatpak</a></p>
</li>
<li>
<p>PDF reader: Evince (GNOME Document Viewer) via <a href="https://flathub.org/apps/org.gnome.Evince">Flatpak</a></p>
</li>
<li>
<p>Image viewer: imv via baseOS</p>
</li>
<li>
<p>Basic photo editing: Drawing via <a href="https://flathub.org/apps/com.github.maoschanz.drawing">Flatpak</a></p>
</li>
<li>
<p>Video player: mpv via <a href="https://flathub.org/apps/io.mpv.Mpv">Flatpak</a> using the flathub repo</p>
</li>
<li>
<p>Torrent client: Transmission via <a href="https://flathub.org/apps/com.transmissionbt.Transmission">Flatpak</a></p>
</li>
<li>File sync
<ul>
<li>Dropbox via <a href="https://flathub.org/apps/com.dropbox.Client">Flatpak</a></li>
<li>Gdrive with rclone via rpm-ostree</li>
</ul>
</li>
<li>
<p>Office suite: LibreOffice via <a href="https://flathub.org/apps/org.libreoffice.LibreOffice">Flatpak</a></p>
</li>
<li>Display setup: wdisplays via rpm-ostree</li>
</ul>
<h2 id="tools">Tools</h2>
<ul>
<li>Shell: bash via baseOS</li>
<li>Terminal multiplexer: tmux in remote systems</li>
<li>Configuration management: Ansible via <a href="https://github.com/josecastillolema/toolbox-images/blob/main/fedora-toolbox-38/Containerfile#L16">toolbx</a></li>
<li>Text editor: neovim via <a href="https://flathub.org/es/apps/io.neovim.nvim">Flatpak</a></li>
<li>Prompt: Starship via local install</li>
<li>Containers: Podman and Toolbx via base OS, Docker in rootless mode via local install
<ul>
<li><a href="https://github.com/josecastillolema/toolbox-images">Toolbx images</a></li>
</ul>
</li>
<li>Virtualization: <a href="https://kcli.readthedocs.io/en/latest/">kcli</a> via <a href="https://github.com/josecastillolema/toolbox-images/blob/main/fedora-toolbox-38/Containerfile#L19-L21">toolbx</a>
<ul>
<li><a href="https://github.com/josecastillolema/kcli-plans">Kcli plans</a></li>
</ul>
</li>
<li>Kubernetes: Kind and kube-burner via local install</li>
<li>Application management: rpm-ostree and Flatpak via baseOS</li>
<li>Keyboard input: wtype via rpm-ostree</li>
</ul>
<h2 id="tricks">Tricks</h2>
<ul>
<li>For <a href="https://github.com/ovn-org/ovn-kubernetes/">ovn-kubernetes</a>:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo modprobe openvswitch
</code></pre></div> </div>
</li>
<li>For <a href="https://kubevirt.io/">KubeVirt</a>:
<ul>
<li>Create the kind cluster as root</li>
<li>The following command will allow the installation of KubeVirt in a rootless cluster but then the VMs won’t be created because rootless docker/podman are unable to create pods in kind with ephemeral storage requests <a href="https://github.com/kubernetes-sigs/kind/issues/3359">kubernetes-sigs/kind#3359</a>:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo chown $USER /dev/kvm
</code></pre></div> </div>
</li>
</ul>
</li>
<li>For <a href="https://github.com/redhat-performance/web-burner">web-burner</a>:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo sysctl -w kernel.keys.maxkeys=5000
</code></pre></div> </div>
</li>
<li>Create a kind cluster using rootless podman as provider without the need of setting systemd property <code class="language-plaintext highlighter-rouge">Delegate=yes</code> (see <a href="https://kind.sigs.k8s.io/docs/user/rootless/">https://kind.sigs.k8s.io/docs/user/rootless/</a>):
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> KIND_EXPERIMENTAL_PROVIDER=podman systemd-run --scope --user ~/go/bin/kind create cluster
</code></pre></div> </div>
</li>
</ul>
<h2 id="issues">Issues</h2>
<p>If you have managed to get working any of the following please let me know:</p>
<ul>
<li>Docker/Podman in rootless mode
<ul>
<li>Unable to create pods in kind with ephemeral storage requests <a href="https://github.com/kubernetes-sigs/kind/issues/3359">kubernetes-sigs/kind#3359</a></li>
</ul>
</li>
<li>Emacs Flatpak
<ul>
<li>^G detaches text-mode emacs from terminal <a href="https://github.com/flathub/org.gnu.emacs/issues/6">flathub/org.gnu.emacs#6</a></li>
<li>Pure-GTK (wayland) support <a href="https://github.com/flathub/org.gnu.emacs/issues/58">flathub/org.gnu.emacs#58</a></li>
</ul>
</li>
<li>Firefox
<ul>
<li>Slack huddles are not available <a href="https://github.com/webcompat/web-bugs/issues/82623">webcompat/web-bugs#82623</a></li>
<li>
<s>Prime Video does not work (neither Chrome nor Firefox) https://www.primevideo.com/region/na/help?nodeId=GU85HKX66NVFNQ9Y</s>
</li>
</ul>
</li>
<li>Nautilus
<ul>
<li>Extract files to current folder <a href="https://www.reddit.com/r/gnome/comments/112a3jq/extract_files_to_current_folder/">r/gnome/112a3jq</a></li>
<li>Nautilus on Flathub <a href="https://gitlab.gnome.org/GNOME/nautilus/-/issues/946">GNOME/nautilus#946</a></li>
</ul>
</li>
<li>Starship
<ul>
<li>Conditional styling for Toolbx symbol <a href="https://github.com/starship/starship/issues/2724">starship/starship#2724</a></li>
</ul>
</li>
<li>Sway
<ul>
<li>
<s>Drag & Drop from XWayland apps to Wayland ones: it only works occasionally [swaywm/sway#6460](https://github.com/swaywm/sway/issues/6460)</s>
</li>
<li>
<s>Differentiate between *app_ids* that start the same [swaywm/sway#7838](https://github.com/swaywm/sway/issues/7838)</s>
</li>
<li>Fast scroll using <em>$mod + ScrollWheel</em>. Tried with:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> bindsym --whole-window $mod+button4 exec "wtype -M shift -k Prior"
bindsym --whole-window $mod+button5 exec "wtype -M shift -k Next"
</code></pre></div> </div>
<ul>
<li>Problem 1: Only works the first wheel turn, then need to relase and press again <em>$mod</em></li>
<li>Problem 2: Different apps use different combinations, i.e.: just <em>ScrollWheel</em> or <em>Shift+ScrollWheel</em></li>
</ul>
</li>
<li>Persistent workspaces <a href="https://github.com/swaywm/sway/pull/7631">swaywm/sway#7631</a></li>
<li>Share a specific window on Google Meet <a href="https://github.com/swaywm/sway/issues/3282">swaywm/sway#3282</a></li>
<li>
<s>XWayland windows gets tiled uppong being reopened from system tray [swaywm/sway#6905](https://github.com/swaywm/sway/issues/6905)</s>
</li>
</ul>
</li>
<li>Toolbx
<ul>
<li>Support for custom commands upon entering container <a href="https://github.com/containers/toolbox/issues/1302">containers/toolbox#1302</a></li>
</ul>
</li>
<li>Vim Flatpak
<ul>
<li>Wayland support <a href="https://github.com/vim/vim/issues/4727">vim/vim#4727</a>, <a href="https://github.com/vim/vim/pull/9639">vim/vim#9639</a></li>
</ul>
</li>
<li>Visual Studio Code
<ul>
<li>Add optional Wayland support <a href="https://github.com/flathub/com.visualstudio.code/issues/471">flathub/com.visualstudio.code#471</a></li>
<li>Crash when rebuilding application menu on wayland <a href="https://github.com/microsoft/vscode/issues/184124">microsoft/vscode#184124</a></li>
<li>Exit Vim Insert Mode on Save <a href="https://github.com/VSCodeVim/Vim/issues/2411">VSCodeVim/Vim#2411</a></li>
<li>
<s>JetBrains Mono font ligatures not working [JetBrains/JetBrainsMono#655](https://github.com/JetBrains/JetBrainsMono/issues/655)</s>
</li>
<li>Paste through mouse middle button does not insert text at cursor position<a href="https://github.com/VSCodeVim/Vim/issues/5065">VSCodeVim/Vim#5065</a></li>
<li>Reset to normal mode when leaving file focus <a href="https://github.com/VSCodeVim/Vim/issues/7553">VSCodeVim/Vim#7553</a></li>
<li>Small/giant mouse cursor <a href="https://github.com/microsoft/vscode/issues/136390">microsoft/vscode#136390</a></li>
</ul>
</li>
<li>Zathura
<ul>
<li>Add Flatpak manifest <a href="https://git.pwmt.org/pwmt/zathura/-/merge_requests/25">pwmt/zathura#25</a></li>
</ul>
</li>
</ul>
<h2 id="todo">TODO</h2>
<ul>
<li>Setup hibernation
<ul>
<li><a href="https://discussion.fedoraproject.org/t/setup-hibernation-on-silverblue-kionite/78834">https://discussion.fedoraproject.org/t/setup-hibernation-on-silverblue-kionite/78834</a></li>
<li><a href="https://bbs.archlinux.org/viewtopic.php?id=259382">https://bbs.archlinux.org/viewtopic.php?id=259382</a></li>
</ul>
</li>
</ul>
<iframe src="https://ghbtns.com/github-btn.html?user=josecastillolema&type=follow&count=true&size=large" frameborder="0" scrolling="0" width="230" height="30" title="GitHub"></iframe>Jose Castillo LemaTelecom cloud-native development: an industry point of view2023-06-02T00:00:00-05:002023-06-02T15:00:58-05:00https://josecastillolema.github.io/imdea<p><a href="https://networks.imdea.org/whatsnew/events-agenda/"><img src="/assets/images/posts/2023-06-02-imdea.png" alt="" /></a></p>
<p>Telcos are increasingly moving from physical/virtual to cloud-native network functions in the context of 5G adoption. In this talk we will describe the telecom network transformation journey, benefits of cloud-native deployments, technical requirements/constraints of the underlying cloud service managers, the role of open source technologies and the use of the operator pattern in telecom contexts.</p>
<p><strong>Event</strong>: <a href="https://networks.imdea.org/whatsnew/events-agenda/telecom-cloud-native-development-an-industry-point-of-view/">link</a></p>
<p><strong>Date</strong>: 9 Jun 2023</p>
<p><strong>Location</strong>: MR-A1 [Ramón] & MR-A2 [Cajal], IMDEA Networks Institute, Avda. del Mar Mediterráneo 22, 28918 Leganés – Madrid</p>
<p><strong>Time</strong>: 12:00</p>
<p><strong>Add to Calendar</strong>: <a href="https://networks.imdea.org/whatsnew/events-agenda/telecom-cloud-native-development-an-industry-point-of-view/#">iCalendar</a> <a href="https://networks.imdea.org/whatsnew/events-agenda/telecom-cloud-native-development-an-industry-point-of-view/#">Outlook</a> <a href="https://www.google.com/calendar/render?action=TEMPLATE&text=Telecom+cloud-native+development%3A+an+industry+point+of+view&dates=20230609T100000Z/20230609T120000Z&details=&location=MR-A1+%5BRam%C3%B3n%5D+%26+MR-A2+%5BCajal%5D%2C+IMDEA+Networks+Institute%2C+Avda.+del+Mar+Mediterr%C3%A1neo+22%2C+28918+Legan%C3%A9s+%E2%80%93+Madrid&sf=true&output=xml">Google</a></p>Jose Castillo Lema