<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://www.cremarenco.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.cremarenco.com/" rel="alternate" type="text/html" /><updated>2026-04-19T17:06:38+02:00</updated><id>https://www.cremarenco.com/feed.xml</id><title type="html">My Homepage</title><subtitle>Welcome to Cosmin Cremarenco&apos;s homepage</subtitle><entry><title type="html">UTM networking on MacOS</title><link href="https://www.cremarenco.com/2025/12/26/macos-packet-forwarding.html" rel="alternate" type="text/html" title="UTM networking on MacOS" /><published>2025-12-26T00:00:00+01:00</published><updated>2025-12-26T00:00:00+01:00</updated><id>https://www.cremarenco.com/2025/12/26/macos-packet-forwarding</id><content type="html" xml:base="https://www.cremarenco.com/2025/12/26/macos-packet-forwarding.html"><![CDATA[<p>If you’re running Sequoia with UTM VMs networking might not work all of a sudden.</p>

<p>The problem is that, for some reason, the new release of MacOs has reset settings of the packet
filtering.</p>

<p>Check if it has the correct value (should be 1):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Check if packet forwarding is enabled
sysctl net.inet.ip.forwarding
</code></pre></div></div>

<p>Otherwise set it correctl:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo sysctl -w net.inet.ip.forwarding=1
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[If you’re running Sequoia with UTM VMs networking might not work all of a sudden.]]></summary></entry><entry><title type="html">Mock modules with jest</title><link href="https://www.cremarenco.com/2025/05/29/jest-mock.html" rel="alternate" type="text/html" title="Mock modules with jest" /><published>2025-05-29T00:00:00+02:00</published><updated>2025-05-29T00:00:00+02:00</updated><id>https://www.cremarenco.com/2025/05/29/jest-mock</id><content type="html" xml:base="https://www.cremarenco.com/2025/05/29/jest-mock.html"><![CDATA[<h1 id="problem">Problem</h1>

<p>Jest is a pretty nice test runner from facebook.
Mocking is easy and hairy at the same time given the nature of Javascript.</p>

<p>Code like:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code>     
     <span class="nx">jest</span><span class="p">.</span><span class="nf">mock</span><span class="p">(</span><span class="dl">"</span><span class="s2">child_process</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span>
                                <span class="na">__esModule</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
                                <span class="na">default</span><span class="p">:</span> <span class="p">{</span> <span class="na">spawn</span><span class="p">:</span> <span class="nx">jest</span><span class="p">.</span><span class="nf">fn</span><span class="p">()</span> <span class="p">}</span>
     <span class="p">});</span>

     <span class="nx">jest</span><span class="p">.</span><span class="nf">doMock</span><span class="p">(</span><span class="dl">"</span><span class="s2">child_process</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span>
                                <span class="na">__esModule</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
                                <span class="na">default</span><span class="p">:</span> <span class="p">{</span> <span class="na">spawn</span><span class="p">:</span> <span class="nx">jest</span><span class="p">.</span><span class="nf">fn</span><span class="p">()</span> <span class="p">}</span>
</code></pre></div></div>

<p>might not work properly.</p>

<h1 id="use-unstable_mockmodule">Use unstable_mockModule</h1>

<p>I found that <code class="language-plaintext highlighter-rouge">jest.unstable_mockModule</code> is a good solution for mocking imported node modules.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Problem Jest is a pretty nice test runner from facebook. Mocking is easy and hairy at the same time given the nature of Javascript. Code like: jest.mock("child_process", () =&gt; ({ __esModule: true, default: { spawn: jest.fn() } }); jest.doMock("child_process", () =&gt; ({ __esModule: true, default: { spawn: jest.fn() } might not work properly. Use unstable_mockModule I found that jest.unstable_mockModule is a good solution for mocking imported node modules.]]></summary></entry><entry><title type="html">Elastic Search systemd unit file</title><link href="https://www.cremarenco.com/2024/02/20/elasticsearch-systemd-unit.html" rel="alternate" type="text/html" title="Elastic Search systemd unit file" /><published>2024-02-20T00:00:00+01:00</published><updated>2024-02-20T00:00:00+01:00</updated><id>https://www.cremarenco.com/2024/02/20/elasticsearch-systemd-unit</id><content type="html" xml:base="https://www.cremarenco.com/2024/02/20/elasticsearch-systemd-unit.html"><![CDATA[<p>Systemd is a system and session manager for Linux operating systems, introduced as the default init system in Fedora 17 and Red Hat Enterprise Linux 7. It replaced the traditional SysVinit and Upstart init systems, providing faster boot times and more efficient resource 
usage.</p>

<p>Systemd manages the runtime behavior of a Linux system, starting and stopping services, managing processes, and handling various other system administration tasks. It provides a drop-in replacement for the traditional init daemon and offers many additional features such as 
mounting file systems, setting up automount points, managing sockets and devices, and more.</p>

<p>Running Elastic Search as a Docker containers on a Linux system managed by Systemd offers several additional advantages:</p>

<ol>
  <li>Easy container management: Systemd makes it easy to manage the lifecycle of Docker containers as part of the system’s startup process. You can create Systemd service files for each Docker container and define how they should be started, stopped, restarted, and reloaded. 
This ensures that your containers are automatically started when the system boots up or when specific events occur.</li>
  <li>Integration with system resources: By running Docker containers under Systemd, you can ensure that your containers have access to essential system resources such as network interfaces, file systems, and environment variables. This is particularly useful for long-running 
services that require consistent access to these resources.</li>
  <li>Automatic failure recovery: Systemd provides automatic failure recovery of services, including Docker containers. If a container fails or crashes, Systemd can automatically restart it based on the service unit file configuration, ensuring high availability and minimal 
downtime.</li>
  <li>Graceful shutdown: When shutting down the system, Systemd can send graceful signals to running Docker containers, allowing them to cleanly stop and save any necessary data or perform orderly shutdown procedures. This helps prevent unexpected data loss or corruption.</li>
  <li>Better integration with system logs and notifications: By using Systemd to manage your Docker containers, you can easily integrate container logs with the system’s logging infrastructure. Additionally, you can use Systemd notifications to be alerted when specific events 
occur within your containers.</li>
  <li>Simplified configuration management: Managing Docker containers under Systemd makes it simpler to configure and deploy applications as part of a larger system or infrastructure. This is particularly useful in production environments where consistent configuration and 
reliable service availability are important.</li>
</ol>

<p>Assuming that Elastic Search was launched as a Docker container with some really common options like so:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run --name es --user elasticsearch:elasticsearch -v /es/data:/data -v /es/repo:/backup -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "cluster.name=bamboo-cluster" -e "node.name=bamboo-cluster-single-node" -e 'http.cors.enabled=true' -e 'http.cors.allow-origin="*"' -e "http.cors.allow-headers: Authorization,Origin,Content-Type,Accept,X-Requested-With" -e 'xpack.security.enabled=false' -e 'path.repo=["/backup"]' -e 'path.data=/data' -e ES_JAVA_OPTS="-Xms4g -Xmx4g" docker.elastic.co/elasticsearch/elasticsearch:8.5.3
</code></pre></div></div>
<p>With an explanation of the different switches below:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">--name es</code>: This option sets the name of the container to “es”. You can use this name later to refer to the container in other commands or scripts.</li>
  <li><code class="language-plaintext highlighter-rouge">--user elasticsearch:elasticsearch</code>: This option sets the user under which the Elasticsearch container should run. In this case, it is set to the default Elasticsearch user (elasticsearch:elasticsearch).</li>
  <li><code class="language-plaintext highlighter-rouge">-v /es/data:/data</code>: This option mounts a local directory (/es/data) as a data volume inside the container at the path /data. This allows persistent data storage for Elasticsearch indexes and configurations.</li>
  <li><code class="language-plaintext highlighter-rouge">-v /es/repo:/backup</code>: Similar to the previous option, this command mounts another local directory (/es/repo) into the container as a backup volume at the path /backup.</li>
  <li><code class="language-plaintext highlighter-rouge">-p 9200:9200</code>: This option binds port 9200 on the host machine to port 9200 inside the container. Elasticsearch usually listens on this port for HTTP requests.</li>
  <li><code class="language-plaintext highlighter-rouge">-p 9300:9300</code>: This option also binds port 9300 on the host machine to port 9300 inside the container. This is the default transport client connection port in Elasticsearch.</li>
  <li><code class="language-plaintext highlighter-rouge">-e "discovery.type=single-node"</code>: This environment variable sets the discovery type of the Elasticsearch cluster to “single-node”, meaning it will not form a distributed cluster and will run as a standalone instance.</li>
  <li><code class="language-plaintext highlighter-rouge">-e "cluster.name=bamboo-cluster"</code>: This option sets the name of the Elasticsearch cluster to “bamboo-cluster”. Cluster names are used to identify and manage clusters in multi-node configurations.</li>
  <li><code class="language-plaintext highlighter-rouge">-e "node.name=bamboo-cluster-single-node"</code>: This environment variable sets the node name inside the cluster to “bamboo-cluster-single-node”. Each node in a cluster has a unique name.</li>
  <li><code class="language-plaintext highlighter-rouge">-e 'http.cors.enabled=true'</code>: Enables Cross-Origin Resource Sharing (CORS) support for Elasticsearch, allowing it to respond to requests coming from different origins than the one it is running on.
<em><code class="language-plaintext highlighter-rouge">-e 'http.cors.allow-origin="*"'</code>: This option sets the allowed CORS origins to “</em>”, meaning all origins are allowed to access Elasticsearch.</li>
  <li><code class="language-plaintext highlighter-rouge">-e "http.cors.allow-headers: Authorization,Origin,Content-Type,Accept,X-Requested-With"</code>: These environment variables set the list of headers that are allowed in CORS requests.
*<code class="language-plaintext highlighter-rouge">-e 'xpack.security.enabled=false'</code>: Disables Elastic Stack Security features, such as encryption at rest and role-based access control, to save resources and simplify the setup.
*<code class="language-plaintext highlighter-rouge">-e 'path.repo=["/backup"]'</code>: Sets the backup repository path to “/backup”. This is used by Elasticsearch for storing its snapshots during backup operations.
*<code class="language-plaintext highlighter-rouge">-e 'path.data=/data'</code>: Sets the data directory path to “/data”, which was already mounted as a volume earlier in this command.
*<code class="language-plaintext highlighter-rouge">-e ES_JAVA_OPTS="-Xms4g -Xmx4g"</code>: This environment variable sets the Java heap size for Elasticsearch, allocating 4GB of heap space (-Xms4g is the minimum heap size and -Xmx4g is the maximum heap size).</li>
</ul>

<p>A Systemd unit file for managing Elastic Search could be the following:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Unit configuration for managing the ElasticSearch Docker container
</span><span class="w">
</span><span class="c"># Description of this unit
</span><span class="nn">[Unit]</span><span class="w">
</span><span class="py">Description</span><span class="p">=</span><span class="s">Manage starting the ElasticSearch Docker container</span>
<span class="py">After</span><span class="p">=</span><span class="s">docker.service       # Start this service only after the docker service is up and running</span>
<span class="py">Requires</span><span class="p">=</span><span class="s">docker.socket      # Ensure that the Docker socket is available</span>
<span class="w">
</span><span class="c">#--------------------------------------------------
# Service configuration
</span><span class="nn">[Service]</span><span class="w">

</span><span class="c"># Always restart the service if it crashes or fails
</span><span class="py">Restart</span><span class="p">=</span><span class="s">always</span>
<span class="w">
</span><span class="c"># Keep the container running after the process terminates
# This is important because Docker will return command immediately after
# launching the container and will not block. Were it not for this line
# Systemd would bail out of the service immediately.
</span><span class="py">RemainAfterExit</span><span class="p">=</span><span class="s">yes</span>
<span class="w">
</span><span class="c"># Attach to the existing Docker container named es.
</span><span class="py">ExecStart</span><span class="p">=</span><span class="s">/bin/sh -c 'docker start --attach es'</span>
<span class="c"># Stop the existing Docker container named es.
</span><span class="py">ExecStop</span><span class="p">=</span><span class="s">/bin/sh -c 'docker stop --time 10 es'</span>
<span class="w">
</span><span class="c"># Wait until ElasticSearch is up and running before moving on to other processes (downstream dependencies)
# This can be essential if any downstream Systemd services depend on the Elastic Search server being
# already up and running by the time they themselves are launched by Systemd.
</span><span class="py">ExecStartPost</span><span class="p">=</span><span class="s">/bin/sh -c 'curl --silent --head --fail --retry 16 --retry-delay 2 --retry-all-errors http://localhost:9200'</span>
<span class="w">
</span><span class="c">#--------------------------------------------------
# Install configuration
</span><span class="nn">[Install]</span><span class="w">
</span><span class="py">WantedBy</span><span class="p">=</span><span class="s">default.target</span>
</code></pre></div></div>

<p>Need help with properly setting up Elastic Search?
Contact us at <a href="https://www.snowlinesoftware.com/contact.php">www.snowlinesoftware.com</a> for help.</p>

<p><img src="https://www.visitorstatus.com/b/ev?depl=1&amp;post=2024-02-20-elasticsearch-systemd-unit.md" alt="" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[Systemd is a system and session manager for Linux operating systems, introduced as the default init system in Fedora 17 and Red Hat Enterprise Linux 7. It replaced the traditional SysVinit and Upstart init systems, providing faster boot times and more efficient resource usage. Systemd manages the runtime behavior of a Linux system, starting and stopping services, managing processes, and handling various other system administration tasks. It provides a drop-in replacement for the traditional init daemon and offers many additional features such as mounting file systems, setting up automount points, managing sockets and devices, and more. Running Elastic Search as a Docker containers on a Linux system managed by Systemd offers several additional advantages: Easy container management: Systemd makes it easy to manage the lifecycle of Docker containers as part of the system’s startup process. You can create Systemd service files for each Docker container and define how they should be started, stopped, restarted, and reloaded. This ensures that your containers are automatically started when the system boots up or when specific events occur. Integration with system resources: By running Docker containers under Systemd, you can ensure that your containers have access to essential system resources such as network interfaces, file systems, and environment variables. This is particularly useful for long-running services that require consistent access to these resources. Automatic failure recovery: Systemd provides automatic failure recovery of services, including Docker containers. If a container fails or crashes, Systemd can automatically restart it based on the service unit file configuration, ensuring high availability and minimal downtime. Graceful shutdown: When shutting down the system, Systemd can send graceful signals to running Docker containers, allowing them to cleanly stop and save any necessary data or perform orderly shutdown procedures. This helps prevent unexpected data loss or corruption. Better integration with system logs and notifications: By using Systemd to manage your Docker containers, you can easily integrate container logs with the system’s logging infrastructure. Additionally, you can use Systemd notifications to be alerted when specific events occur within your containers. Simplified configuration management: Managing Docker containers under Systemd makes it simpler to configure and deploy applications as part of a larger system or infrastructure. This is particularly useful in production environments where consistent configuration and reliable service availability are important. Assuming that Elastic Search was launched as a Docker container with some really common options like so: docker run --name es --user elasticsearch:elasticsearch -v /es/data:/data -v /es/repo:/backup -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "cluster.name=bamboo-cluster" -e "node.name=bamboo-cluster-single-node" -e 'http.cors.enabled=true' -e 'http.cors.allow-origin="*"' -e "http.cors.allow-headers: Authorization,Origin,Content-Type,Accept,X-Requested-With" -e 'xpack.security.enabled=false' -e 'path.repo=["/backup"]' -e 'path.data=/data' -e ES_JAVA_OPTS="-Xms4g -Xmx4g" docker.elastic.co/elasticsearch/elasticsearch:8.5.3 With an explanation of the different switches below: --name es: This option sets the name of the container to “es”. You can use this name later to refer to the container in other commands or scripts. --user elasticsearch:elasticsearch: This option sets the user under which the Elasticsearch container should run. In this case, it is set to the default Elasticsearch user (elasticsearch:elasticsearch). -v /es/data:/data: This option mounts a local directory (/es/data) as a data volume inside the container at the path /data. This allows persistent data storage for Elasticsearch indexes and configurations. -v /es/repo:/backup: Similar to the previous option, this command mounts another local directory (/es/repo) into the container as a backup volume at the path /backup. -p 9200:9200: This option binds port 9200 on the host machine to port 9200 inside the container. Elasticsearch usually listens on this port for HTTP requests. -p 9300:9300: This option also binds port 9300 on the host machine to port 9300 inside the container. This is the default transport client connection port in Elasticsearch. -e "discovery.type=single-node": This environment variable sets the discovery type of the Elasticsearch cluster to “single-node”, meaning it will not form a distributed cluster and will run as a standalone instance. -e "cluster.name=bamboo-cluster": This option sets the name of the Elasticsearch cluster to “bamboo-cluster”. Cluster names are used to identify and manage clusters in multi-node configurations. -e "node.name=bamboo-cluster-single-node": This environment variable sets the node name inside the cluster to “bamboo-cluster-single-node”. Each node in a cluster has a unique name. -e 'http.cors.enabled=true': Enables Cross-Origin Resource Sharing (CORS) support for Elasticsearch, allowing it to respond to requests coming from different origins than the one it is running on. -e 'http.cors.allow-origin="*"': This option sets the allowed CORS origins to “”, meaning all origins are allowed to access Elasticsearch. -e "http.cors.allow-headers: Authorization,Origin,Content-Type,Accept,X-Requested-With": These environment variables set the list of headers that are allowed in CORS requests. *-e 'xpack.security.enabled=false': Disables Elastic Stack Security features, such as encryption at rest and role-based access control, to save resources and simplify the setup. *-e 'path.repo=["/backup"]': Sets the backup repository path to “/backup”. This is used by Elasticsearch for storing its snapshots during backup operations. *-e 'path.data=/data': Sets the data directory path to “/data”, which was already mounted as a volume earlier in this command. *-e ES_JAVA_OPTS="-Xms4g -Xmx4g": This environment variable sets the Java heap size for Elasticsearch, allocating 4GB of heap space (-Xms4g is the minimum heap size and -Xmx4g is the maximum heap size). A Systemd unit file for managing Elastic Search could be the following: # Unit configuration for managing the ElasticSearch Docker container # Description of this unit [Unit] Description=Manage starting the ElasticSearch Docker container After=docker.service # Start this service only after the docker service is up and running Requires=docker.socket # Ensure that the Docker socket is available #-------------------------------------------------- # Service configuration [Service] # Always restart the service if it crashes or fails Restart=always # Keep the container running after the process terminates # This is important because Docker will return command immediately after # launching the container and will not block. Were it not for this line # Systemd would bail out of the service immediately. RemainAfterExit=yes # Attach to the existing Docker container named es. ExecStart=/bin/sh -c 'docker start --attach es' # Stop the existing Docker container named es. ExecStop=/bin/sh -c 'docker stop --time 10 es' # Wait until ElasticSearch is up and running before moving on to other processes (downstream dependencies) # This can be essential if any downstream Systemd services depend on the Elastic Search server being # already up and running by the time they themselves are launched by Systemd. ExecStartPost=/bin/sh -c 'curl --silent --head --fail --retry 16 --retry-delay 2 --retry-all-errors http://localhost:9200' #-------------------------------------------------- # Install configuration [Install] WantedBy=default.target Need help with properly setting up Elastic Search? Contact us at www.snowlinesoftware.com for help.]]></summary></entry><entry><title type="html">Properly forward signals to Docker container process and ENV vars</title><link href="https://www.cremarenco.com/2024/01/18/init2.html" rel="alternate" type="text/html" title="Properly forward signals to Docker container process and ENV vars" /><published>2024-01-18T00:00:00+01:00</published><updated>2024-01-18T00:00:00+01:00</updated><id>https://www.cremarenco.com/2024/01/18/init2</id><content type="html" xml:base="https://www.cremarenco.com/2024/01/18/init2.html"><![CDATA[<h1 id="problem">Problem</h1>

<p>Correctly handling certain use cases requires that containers running under Docker properly receive and handle sent signals. It comes to mind graceful process termination when systemd will send a SIGTERM to the process giving it a chance to cleanly stop before it’s being sent a SIGKILL that results in immediate process stop. Handling signals in this case is quite simple and well-documented, either using the newer <code class="language-plaintext highlighter-rouge">sigaction</code> function or the older <code class="language-plaintext highlighter-rouge">signal</code>. However, if the process ran by systemd is in fact a Docker container then things are not so simple.</p>

<p>The Docker daemon will forward signals to the process running inside the container with PID=1. When running outside a container, that’s usually process <em>init</em>, the root of all the process hierarchy. <em>Inside</em> a container, however, the process, may or may not be the root process (thus having PID = 1).</p>

<p>Example: Dockerfile using the shell form for CMD or ENTRYPOINT:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CMD “echo ‘hello world’”
ENTRYPOINT “echo ‘hello world’”
</code></pre></div></div>

<p>These will result in an execution under the shell:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/bin/bash -c “echo ‘hello world’”
</code></pre></div></div>

<p>What this means is that the shell process (<em>bash</em> here) will have PID=1, therefore it is the shell that will get signals sent by Docker. The “echo” process running above will not receive those signals.</p>

<h1 id="exec-form">exec form</h1>

<p>What is recommended in this case is running the <em>exec</em> form for CMD or ENTRYPOINT where the arguments are inside a JSON array, as below:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CMD [“echo”, “hello world’]
ENTRYPOINT [“echo”, “hello world”]
</code></pre></div></div>
<p>Now the <em>echo</em>  process will have PID=1 and will properly receive all the signals. 
This works very well. 
Unless, the shell is needed.</p>

<h1 id="environment-variable-substitution">Environment variable substitution</h1>

<p>Environment ariable substitution for environment variables declared as <em>ENV</em> in the Dockerfile does not work with exec form. 
A shell would be needed in order to perform that substitution.</p>

<p>What’s needed is a custom process that properly forwards signals to children processes, but that also properly does variable substitutions and passes expanded environment variables to launched children processes.</p>

<p>Check the <a href="https://github.com/ccosmin/init2">init2</a> for a possible solution.</p>

<p><img src="https://www.visitorstatus.com/b/ev?depl=1&amp;post=2024-01-18-init2.md" alt="" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[Problem Correctly handling certain use cases requires that containers running under Docker properly receive and handle sent signals. It comes to mind graceful process termination when systemd will send a SIGTERM to the process giving it a chance to cleanly stop before it’s being sent a SIGKILL that results in immediate process stop. Handling signals in this case is quite simple and well-documented, either using the newer sigaction function or the older signal. However, if the process ran by systemd is in fact a Docker container then things are not so simple. The Docker daemon will forward signals to the process running inside the container with PID=1. When running outside a container, that’s usually process init, the root of all the process hierarchy. Inside a container, however, the process, may or may not be the root process (thus having PID = 1). Example: Dockerfile using the shell form for CMD or ENTRYPOINT: CMD “echo ‘hello world’” ENTRYPOINT “echo ‘hello world’” These will result in an execution under the shell: /usr/bin/bash -c “echo ‘hello world’” What this means is that the shell process (bash here) will have PID=1, therefore it is the shell that will get signals sent by Docker. The “echo” process running above will not receive those signals. exec form What is recommended in this case is running the exec form for CMD or ENTRYPOINT where the arguments are inside a JSON array, as below: CMD [“echo”, “hello world’] ENTRYPOINT [“echo”, “hello world”] Now the echo process will have PID=1 and will properly receive all the signals. This works very well. Unless, the shell is needed. Environment variable substitution Environment ariable substitution for environment variables declared as ENV in the Dockerfile does not work with exec form. A shell would be needed in order to perform that substitution. What’s needed is a custom process that properly forwards signals to children processes, but that also properly does variable substitutions and passes expanded environment variables to launched children processes. Check the init2 for a possible solution.]]></summary></entry><entry><title type="html">How to disable the merge button in a GitLab merge request</title><link href="https://www.cremarenco.com/2023/10/06/forbid-merging-in-gitlab.html" rel="alternate" type="text/html" title="How to disable the merge button in a GitLab merge request" /><published>2023-10-06T00:00:00+02:00</published><updated>2023-10-06T00:00:00+02:00</updated><id>https://www.cremarenco.com/2023/10/06/forbid-merging-in-gitlab</id><content type="html" xml:base="https://www.cremarenco.com/2023/10/06/forbid-merging-in-gitlab.html"><![CDATA[<h1 id="problem">Problem</h1>

<p>There are times when it’s interesting to disable the possibility to merge
a merge request. The merge request might be in a mirrored repository, or you might
just prefer manually merging branches.</p>

<h1 id="solution">Solution</h1>

<p>The “Merge” button behaviour (enabled/disabled) is driven by the method <code class="language-plaintext highlighter-rouge">isMergeButtonDisabled</code>
which returns a boolean indicating whether the merge button should be disabled or not.</p>

<p>The cleanest way to modify this behaviour is to tinker with the Vue files that Gitlab comes with.
However, since these components are not served directly (they are compiled and bundled using
webpack) this means that compilation is needed, which might be a hassle.</p>

<p>The other way is to modify the webpack bundle directly.
The instructions below are for a self-hosted Gitlab instance, Debian install, version 15.8.
But they probably apply with minimal modifications to Omnibus as well.</p>

<p>Warning: At this point I’m assuming you know what you’re doing, or otherwise you risk crippling your
Gitlab installation.</p>

<p>Your mileage may vary but my bundle is stored in <code class="language-plaintext highlighter-rouge">/var/lib/gitlab/public/assets/webpack</code>
(this is a Debian distrib Gitlab).
Go into this directory and do:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>grep isMergeButtonDisabled * | cut -f1 -d:
</code></pre></div></div>
<p>A match should be in a file called <code class="language-plaintext highlighter-rouge">pages.projects.merge_requests.show.*.chunk.js</code>.
Edit this file (make sure to do a backup first), 
search for <code class="language-plaintext highlighter-rouge">isMergeButtonDisabled</code>. Change the function to read instead of:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>isMergeButtonDisabled(){const{commitMessage....
</code></pre></div></div>
<p>to:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>isMergeButtonDisabled(){return true;const{commitMessage....
</code></pre></div></div>

<p>Don’t forget to remove the <code class="language-plaintext highlighter-rouge">pages.projects.merge_requests.show.*.chunk.js.gz</code> as
otherwise that one will be served instead of the modified version.
Alternatively you can also use <code class="language-plaintext highlighter-rouge">gzip</code> in order to replace the existing archive.</p>

<p>Need help with setting up Gitlab?
Contact us at <a href="https://www.snowlinesoftware.com/contact.php">www.snowlinesoftware.com</a> for help.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Problem There are times when it’s interesting to disable the possibility to merge a merge request. The merge request might be in a mirrored repository, or you might just prefer manually merging branches. Solution The “Merge” button behaviour (enabled/disabled) is driven by the method isMergeButtonDisabled which returns a boolean indicating whether the merge button should be disabled or not. The cleanest way to modify this behaviour is to tinker with the Vue files that Gitlab comes with. However, since these components are not served directly (they are compiled and bundled using webpack) this means that compilation is needed, which might be a hassle. The other way is to modify the webpack bundle directly. The instructions below are for a self-hosted Gitlab instance, Debian install, version 15.8. But they probably apply with minimal modifications to Omnibus as well. Warning: At this point I’m assuming you know what you’re doing, or otherwise you risk crippling your Gitlab installation. Your mileage may vary but my bundle is stored in /var/lib/gitlab/public/assets/webpack (this is a Debian distrib Gitlab). Go into this directory and do: grep isMergeButtonDisabled * | cut -f1 -d: A match should be in a file called pages.projects.merge_requests.show.*.chunk.js. Edit this file (make sure to do a backup first), search for isMergeButtonDisabled. Change the function to read instead of: isMergeButtonDisabled(){const{commitMessage.... to: isMergeButtonDisabled(){return true;const{commitMessage.... Don’t forget to remove the pages.projects.merge_requests.show.*.chunk.js.gz as otherwise that one will be served instead of the modified version. Alternatively you can also use gzip in order to replace the existing archive. Need help with setting up Gitlab? Contact us at www.snowlinesoftware.com for help.]]></summary></entry><entry><title type="html">Welcome to my blog!</title><link href="https://www.cremarenco.com/life/2023/09/15/first-post.html" rel="alternate" type="text/html" title="Welcome to my blog!" /><published>2023-09-15T15:45:23+02:00</published><updated>2023-09-15T15:45:23+02:00</updated><id>https://www.cremarenco.com/life/2023/09/15/first-post</id><content type="html" xml:base="https://www.cremarenco.com/life/2023/09/15/first-post.html"><![CDATA[<p>I’m moving from WordPress to Jekyll, expect to see more posts here soon.</p>]]></content><author><name></name></author><category term="life" /><summary type="html"><![CDATA[I’m moving from WordPress to Jekyll, expect to see more posts here soon.]]></summary></entry></feed>