<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Konstantin Tutsch</title>
        <link>https://konstantintutsch.com</link>
        <atom:link href="https://konstantintutsch.com/feed.xml" rel="self" type="application/rss+xml" />
        <description>The RSS feed for Konstantin Tutsch's blog.</description>
        <lastBuildDate>Mon, 06 Apr 2026 12:03:06 +0200</lastBuildDate>
        <item>
            <title>Grant Docker Access To Volume on SELinux Enforced System</title>
            <link>https://konstantintutsch.com/blog/docker-volume-grant-selinux-permissions/</link>
            <description>
                &lt;p&gt;When running Docker on a system enforcing SELinux, Docker Volumes require a special &lt;strong&gt;SELinux context&lt;/strong&gt; to be accessible by the Docker Daemon and Container.&lt;/p&gt;
&lt;p&gt;This context is called &lt;code&gt;container_file_t&lt;/code&gt; and can be &lt;strong&gt;set on a path recursively&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;semanage fcontext -a -t container_file_t &amp;quot;&amp;lt;path&amp;gt;(/.*)?&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards, the context needs to be &lt;strong&gt;applied to already existing files&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;restorecon -Rv &amp;lt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; is now usable by Docker as a volume! 🥳&lt;/p&gt;

            </description>
            <pubDate>Mon, 17 Nov 2025 15:06:00 +0100</pubDate>
            <guid>https://konstantintutsch.com/blog/docker-volume-grant-selinux-permissions/</guid>
        </item>
        <item>
            <title>How To Compile a Java Program with Multiple Source Files</title>
            <link>https://konstantintutsch.com/blog/compile-java-from-multiple-source-files/</link>
            <description>
                &lt;p&gt;This blog post is just another note to my future self. This time, it is about compiling &lt;em&gt;(and running)&lt;/em&gt; a Java application &lt;em&gt;(with multiple source files)&lt;/em&gt; from only the command line.&lt;/p&gt;
&lt;h2 id=&quot;the-example-program&quot; tabindex=&quot;-1&quot;&gt;The Example Program&lt;/h2&gt;
&lt;p&gt;Let&#39;s say, our application is made up of two files: &lt;code&gt;Main.java&lt;/code&gt; and &lt;code&gt;Combination.java&lt;/code&gt;. In this example, their contents look like this …&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// Main.java

package com.konstantintutsch.Example;

public class Main
{
    private static Combination c;

    public static void main(String[] args)
    {
        c = new Combination(&amp;quot;Hello, World!&amp;quot;, 42);

        System.out.println(c.getText() + &amp;quot; (&amp;quot; + c.getNumber() + &amp;quot;)&amp;quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;… and like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Combination.java

package com.konstantintutsch.Example;

public class Combination
{
    // Attributes
    private String text;
    private int number;

    // Methods
    public Combination(String text, int number) // Constructor
    {
        this.text = text;
        this.number = number;
    }

    // text
    public String getText()
    {
        return this.text;
    }
    public void setText(String text)
    {
        this.text = text;
    }

    // number
    public int getNumber()
    {
        return this.number;
    }
    public void setNumber(int number)
    {
        this.number = number;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, our entry point into the code of our program is the class &lt;code&gt;Main&lt;/code&gt; from &lt;code&gt;Main.java&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;compiling&quot; tabindex=&quot;-1&quot;&gt;Compiling&lt;/h2&gt;
&lt;p&gt;If we want to compile and later execute this code, we need to create a JAR file.&lt;/p&gt;
&lt;p&gt;Here&#39;s the procedure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Compile all &lt;code&gt;.java&lt;/code&gt; source files to &lt;code&gt;.class&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Bundle these &lt;code&gt;.class&lt;/code&gt; files into a &lt;code&gt;.jar&lt;/code&gt; file&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;commands&quot; tabindex=&quot;-1&quot;&gt;Commands&lt;/h3&gt;
&lt;p&gt;The procedure, but translated into commands, looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir ./build
javac -d ./build Main.java Combination.java
jar cfe ./build/Build.jar com.konstantintutsch.Example.Main -C ./build com
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;explanation&quot; tabindex=&quot;-1&quot;&gt;Explanation&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;javac&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-d ./build&lt;/code&gt;: write all &lt;code&gt;.class&lt;/code&gt; files to &lt;code&gt;./build/&amp;lt;PACKAGE&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*.java&lt;/code&gt;: file(s) to be compiled&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jar&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;c&lt;/code&gt;: create a JAR&lt;/li&gt;
&lt;li&gt;&lt;code&gt;f&lt;/code&gt;: write the archive to a file (&lt;code&gt;./build/Build.jar&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;e&lt;/code&gt;: use a class as the entry point (&lt;code&gt;com.konstantintutsch.Example.Main&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C ./build com&lt;/code&gt;: bundle all &lt;code&gt;.class&lt;/code&gt; files in the directory &lt;code&gt;./build&lt;/code&gt; from the namespace &lt;code&gt;com&lt;/code&gt; (also &lt;code&gt;com.konstantintutsch.Example&lt;/code&gt;) into the archive&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;makefile&quot; tabindex=&quot;-1&quot;&gt;Makefile&lt;/h4&gt;
&lt;p&gt;If you don&#39;t want to retype these same commands every time you change something in your code, write a Makefile:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-makefile&quot;&gt;#
# Package
#

NAMESPACE := com
PACKAGE := $(NAMESPACE).konstantintutsch.Template

#
# Files
#

SOURCES := $(wildcard *.java)

BUILDDIR := build
EXECUTABLE := Build.jar

#
# Compilers
#

JC := javac
JCFLAGS := -d $(BUILDDIR)

JR := jar

#
# Build
#

$(BUILDDIR):
	mkdir -p $(BUILDDIR)

$(BUILDDIR)/$(EXECUTABLE): $(BUILDDIR)
	$(JC) $(JCFLAGS) $(SOURCES)
	$(JR) cfe $(BUILDDIR)/$(EXECUTABLE) $(PACKAGE).Main -C $(BUILDDIR) $(NAMESPACE)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compiling now looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make build/Build.jar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Much shorter!&lt;/p&gt;
&lt;h2 id=&quot;executing&quot; tabindex=&quot;-1&quot;&gt;Executing&lt;/h2&gt;
&lt;p&gt;The last thing to do now is to run the code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ java -jar ./build/Build.jar
Hello, World! (42)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look at that! It worked!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;At least on my end …&lt;/em&gt;&lt;/p&gt;

            </description>
            <pubDate>Thu, 05 Sep 2024 18:12:52 +0200</pubDate>
            <guid>https://konstantintutsch.com/blog/compile-java-from-multiple-source-files/</guid>
        </item>
        <item>
            <title>How-To Use BeaconDB as Your Geolocation Provider on Linux</title>
            <link>https://konstantintutsch.com/blog/beacondb-geolocation-on-linux-gnome/</link>
            <description>
                &lt;h2 id=&quot;mls-and-it&#39;s-alternative&quot; tabindex=&quot;-1&quot;&gt;MLS and It&#39;s Alternative&lt;/h2&gt;
&lt;p&gt;On March 13, 2024, Mozilla decided to retire their geolocation service and database.&lt;sup&gt;&lt;a href=&quot;https://konstantintutsch.com/blog/beacondb-geolocation-on-linux-gnome/#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is probably the reason you are currently reading this post and I can also safely assume that your system is not able to locate itself anymore. No worries though, there&#39;s a quick fix.&lt;/p&gt;
&lt;p&gt;It&#39;s &lt;a href=&quot;https://beacondb.net/&quot;&gt;BeaconDB&lt;/a&gt;! An open-source alternative to the Mozilla Location Service. It&#39;s still in an experimental stage, but already pretty mature. And to our luck, also uses the same request format as Mozilla.&lt;sup&gt;&lt;a href=&quot;https://konstantintutsch.com/blog/beacondb-geolocation-on-linux-gnome/#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-fix%2C-at-least-with-gnome-via-geoclue&quot; tabindex=&quot;-1&quot;&gt;The Fix, at least with GNOME via Geoclue&lt;/h2&gt;
&lt;p&gt;On most Linux distributions, location services are provided by a service called Geoclue. Though by default, current and older versions of Geoclue are configured to use MLS as their geolocation database.&lt;/p&gt;
&lt;p&gt;That&#39;s a problem when MLS doesn&#39;t work. And that is the case forever now. Fortunately, switching over to BeaconDB is easy.&lt;/p&gt;
&lt;p&gt;First, find &lt;code&gt;geoclue.conf&lt;/code&gt;. It&#39;s location differs on different distributions with different package manages. On Fedora, you can find it at &lt;code&gt;/etc/geoclue/geoclue.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once found, edit the file as &lt;code&gt;root&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-conf&quot;&gt;[wifi]
enabled=true
url=https://beacondb.net/v1/geolocate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To apply the configuration change, restart the Geoclue service. On systems using SystemD, do this (and be &lt;code&gt;root&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart geoclue.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s it. Open an app that&#39;s using location services and try out your system&#39;s regained capabilities!&lt;/p&gt;
&lt;h2 id=&quot;troubleshooting&quot; tabindex=&quot;-1&quot;&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;If your system indefinitely tries to locate itself without any success or even fails, your area might not be indexed.&lt;sup&gt;&lt;a href=&quot;https://konstantintutsch.com/blog/beacondb-geolocation-on-linux-gnome/#fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Have a look at the &lt;a href=&quot;https://beacondb.net/#contribute&quot;&gt;BeaconDB website&lt;/a&gt; to find out which contribution options might be viable to you. Have fun!&lt;/p&gt;

            </description>
            <pubDate>Tue, 13 Aug 2024 18:35:40 +0200</pubDate>
            <guid>https://konstantintutsch.com/blog/beacondb-geolocation-on-linux-gnome/</guid>
        </item>
        <item>
            <title>Multiple Push URLs for a Single Git Remote</title>
            <link>https://konstantintutsch.com/blog/multiple-push-urls-single-git-remote/</link>
            <description>
                &lt;p&gt;This post is just a note to my future self on how to add multiple push URLs to a single git remote.&lt;/p&gt;
&lt;h2 id=&quot;adding-the-urls&quot; tabindex=&quot;-1&quot;&gt;Adding The URLs&lt;/h2&gt;
&lt;p&gt;First, add a new remote to your git repository.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote add all git@server1:repo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, redefine the push URL of the remote.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote set-url --add --push all git@server1:repo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, add the URL of your second remote.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote set-url --add --push all git@server2:repo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;confirming-the-changes&quot; tabindex=&quot;-1&quot;&gt;Confirming The Changes&lt;/h2&gt;
&lt;p&gt;At the end, confirm that all URLs were set correctly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output should now be similar to this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;all	git@server1:repo.git (fetch)
all	git@server1:repo.git (push)
all	git@server2:repo.git (push)
&lt;/code&gt;&lt;/pre&gt;

            </description>
            <pubDate>Fri, 12 Jul 2024 10:23:00 +0200</pubDate>
            <guid>https://konstantintutsch.com/blog/multiple-push-urls-single-git-remote/</guid>
        </item>
    </channel>
</rss>
