Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions pkg/integrations/gitlab/glrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ func (args *GitLabRunnerArgs) GetUserDataValues() *integrations.UserDataValues {
return nil
}
return &integrations.UserDataValues{
Name: args.Name,
Token: args.AuthToken, // Use auth token (set by Pulumi during deployment)
CliURL: downloadURL(),
RepoURL: args.URL,
Unsecure: args.Unsecure,
Concurrent: args.Concurrent,
Name: args.Name,
Token: args.AuthToken, // Use auth token (set by Pulumi during deployment)
CliURL: downloadURL(),
RepoURL: args.URL,
Unsecure: args.Unsecure,
Concurrent: args.Concurrent,
LogToJournald: args.LogToJournald,
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/integrations/gitlab/snippet-darwin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ sudo gitlab-runner register \
--non-interactive \
--url "{{ .RepoURL }}" \
--token "{{ .Token }}" \
--name "{{ .Name }}" \
--executor "shell"

# Install and start as LaunchDaemon
Expand Down
154 changes: 153 additions & 1 deletion pkg/integrations/gitlab/snippet-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,168 @@ sudo restorecon -v /usr/bin/gitlab-runner 2>/dev/null || true
# Enable Podman socket so the docker executor can reach it
sudo systemctl enable --now podman.socket

# Detect the host's upstream DNS servers and propagate them into every Podman
# container (including nested build containers created by `podman build`).
# Without this, inner build containers inherit a loopback stub address
# (127.0.0.53 / systemd-resolved) that is unreachable from inside a container,
# causing DNS resolution failures like "Could not resolve host: github.com".
_dns_servers=""
if command -v resolvectl &>/dev/null; then
_dns_servers=$(resolvectl dns 2>/dev/null \
| awk '{for(i=2;i<=NF;i++) print $i}' \
| grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' \
| sort -u | tr '\n' ' ' | xargs)
fi
if [ -z "$_dns_servers" ] && command -v nmcli &>/dev/null; then
_dns_servers=$(nmcli dev show 2>/dev/null \
| awk '/IP4\.DNS/ {print $2}' \
| tr '\n' ' ' | xargs)
fi
# On systemd-resolved systems (Ubuntu), /run/systemd/resolve/resolv.conf holds
# the real upstream DNS servers (not the 127.0.0.53 stub in /etc/resolv.conf).
if [ -z "$_dns_servers" ]; then
_dns_servers=$(awk '/^nameserver/ && $2 !~ /^127\./ && $2 != "::1" {print $2}' \
/run/systemd/resolve/resolv.conf 2>/dev/null \
| tr '\n' ' ' | xargs)
fi
if [ -z "$_dns_servers" ]; then
_dns_servers=$(awk '/^nameserver/ && $2 !~ /^127\./ && $2 != "::1" {print $2}' /etc/resolv.conf \
| tr '\n' ' ' | xargs)
fi
# Last-resort fallback: if no local DNS could be detected, use public resolvers.
# The machine must have internet access (it talks to GitLab), so these will work.
if [ -z "$_dns_servers" ]; then
_dns_servers="8.8.8.8 8.8.4.4"
fi
# Build --docker-dns flags for runner registration so every job container gets
# working DNS servers even when Podman's Docker socket API does not honour
# containers.conf dns_servers (which affects executor-container resolution).
_docker_dns_args=()
for _ip in $_dns_servers; do
_docker_dns_args+=(--docker-dns "$_ip")
done

if [ -n "$_dns_servers" ]; then
_toml_list=""
for _ip in $_dns_servers; do
[ -n "$_toml_list" ] && _toml_list="${_toml_list}, "
_toml_list="${_toml_list}\"${_ip}\""
done
sudo mkdir -p /etc/containers
if [ ! -f /etc/containers/containers.conf ]; then
printf '[containers]\ndns_servers = [%s]\ndns_options = ["timeout:2", "attempts:5", "single-request"]\n' \
"$_toml_list" | sudo tee /etc/containers/containers.conf > /dev/null
elif grep -q '^\[containers\]' /etc/containers/containers.conf; then
# Scope the dns_servers check to the [containers] section only
if awk '/^\[containers\]/{f=1;next} /^\[/{f=0} f && /^dns_servers/{found=1} END{exit !found}' \
/etc/containers/containers.conf; then
# Replace dns_servers only within [containers]
awk -v "val=dns_servers = [${_toml_list}]" \
'/^\[containers\]/{s=1} /^\[/ && !/^\[containers\]/{s=0}
s && /^dns_servers/{$0=val} 1' \
/etc/containers/containers.conf \
| sudo tee /etc/containers/containers.conf.tmp > /dev/null \
&& sudo mv /etc/containers/containers.conf.tmp /etc/containers/containers.conf
else
sudo sed -i "/^\[containers\]/a dns_servers = [${_toml_list}]" \
/etc/containers/containers.conf
Comment thread
coderabbitai[bot] marked this conversation as resolved.
fi
# Add or update dns_options within [containers]
if grep -q '^dns_options' /etc/containers/containers.conf; then
sudo sed -i 's|^dns_options.*|dns_options = ["timeout:2", "attempts:5", "single-request"]|' \
/etc/containers/containers.conf
else
sudo sed -i '/^\[containers\]/a dns_options = ["timeout:2", "attempts:5", "single-request"]' \
/etc/containers/containers.conf
Comment on lines +84 to +89

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Scope dns_options edits to the [containers] section.

Line 84 checks dns_options globally, and Line 85 replaces it globally. If another section defines dns_options, [containers].dns_options may remain unset (or unrelated sections get modified), causing inconsistent Podman DNS behavior.

Proposed fix
-        # Add or update dns_options within [containers]
-        if grep -q '^dns_options' /etc/containers/containers.conf; then
-            sudo sed -i 's|^dns_options.*|dns_options = ["timeout:2", "attempts:5", "single-request"]|' \
-                /etc/containers/containers.conf
+        # Add or update dns_options within [containers]
+        if awk '/^\[containers\]/{f=1;next} /^\[/{f=0} f && /^[[:space:]]*dns_options[[:space:]]*=/{found=1} END{exit !found}' \
+                /etc/containers/containers.conf; then
+            sudo sed -i '/^\[containers\]/,/^\[/{s|^[[:space:]]*dns_options[[:space:]]*=.*|dns_options = ["timeout:2", "attempts:5", "single-request"]|}' \
+                /etc/containers/containers.conf
         else
             sudo sed -i '/^\[containers\]/a dns_options = ["timeout:2", "attempts:5", "single-request"]' \
                 /etc/containers/containers.conf
         fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if grep -q '^dns_options' /etc/containers/containers.conf; then
sudo sed -i 's|^dns_options.*|dns_options = ["timeout:2", "attempts:5", "single-request"]|' \
/etc/containers/containers.conf
else
sudo sed -i '/^\[containers\]/a dns_options = ["timeout:2", "attempts:5", "single-request"]' \
/etc/containers/containers.conf
# Add or update dns_options within [containers]
if awk '/^\[containers\]/{f=1;next} /^\[/{f=0} f && /^[[:space:]]*dns_options[[:space:]]*=/{found=1} END{exit !found}' \
/etc/containers/containers.conf; then
sudo sed -i '/^\[containers\]/,/^\[/{s|^[[:space:]]*dns_options[[:space:]]*=.*|dns_options = ["timeout:2", "attempts:5", "single-request"]|}' \
/etc/containers/containers.conf
else
sudo sed -i '/^\[containers\]/a dns_options = ["timeout:2", "attempts:5", "single-request"]' \
/etc/containers/containers.conf
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/integrations/gitlab/snippet-linux.sh` around lines 84 - 89, The grep
check on line 84 searches for dns_options globally in the file without scoping
it to the [containers] section, and the subsequent sed replacement on line 85
also operates globally. This can cause unintended modifications to dns_options
in other sections or leave [containers].dns_options unset. Modify the grep
pattern to specifically check for dns_options within the [containers] section
(for example, by using a pattern that matches dns_options after the [containers]
header), and update the sed command on line 85 to scope the replacement to only
the [containers] section to ensure consistent Podman DNS configuration.

fi
else
printf '\n[containers]\ndns_servers = [%s]\ndns_options = ["timeout:2", "attempts:5", "single-request"]\n' \
"$_toml_list" | sudo tee -a /etc/containers/containers.conf > /dev/null
fi
# Ensure the file is world-readable so rootless Podman can also load it
sudo chmod 644 /etc/containers/containers.conf
fi

# Guarantee the file exists even when DNS detection found nothing, so that the
# volume mount added to the runner below always has a real file to bind.
sudo mkdir -p /etc/containers
if [ ! -f /etc/containers/containers.conf ]; then
printf '[containers]\n' | sudo tee /etc/containers/containers.conf > /dev/null
sudo chmod 644 /etc/containers/containers.conf
fi

{{- if .LogToJournald}}
# Set journald as the container log driver so CI job output is captured by the
# systemd journal and can be correlated with runner daemon logs via job_id.
sudo mkdir -p /etc/containers
if [ ! -f /etc/containers/containers.conf ]; then
printf '[containers]\nlog_driver = "journald"\n' \
| sudo tee /etc/containers/containers.conf > /dev/null
elif grep -q '^\[containers\]' /etc/containers/containers.conf; then
if awk '/^\[containers\]/{f=1;next} /^\[/{f=0} f && /^log_driver/{found=1} END{exit !found}' \
/etc/containers/containers.conf; then
# Replace existing log_driver within [containers]
awk '/^\[containers\]/{s=1} /^\[/ && !/^\[containers\]/{s=0}
s && /^log_driver/{$0="log_driver = \"journald\""} 1' \
/etc/containers/containers.conf \
| sudo tee /etc/containers/containers.conf.tmp > /dev/null \
&& sudo mv /etc/containers/containers.conf.tmp /etc/containers/containers.conf
else
sudo sed -i '/^\[containers\]/a log_driver = "journald"' \
/etc/containers/containers.conf
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
else
printf '\n[containers]\nlog_driver = "journald"\n' \
| sudo tee -a /etc/containers/containers.conf > /dev/null
fi
sudo chmod 644 /etc/containers/containers.conf
{{- end}}

# Create an executor-specific containers.conf that adds a non-conflicting inner
# subnet for nested Netavark networks. The host containers.conf intentionally
# omits [network] so the host Podman bridge keeps its default 10.88.0.0/16.
# The executor copy adds default_subnet = 192.168.100.0/24 so that Netavark
# inside a privileged executor container creates a bridge in a different subnet,
# eliminating the duplicate-route conflict that breaks DNS in nested containers
# on Netavark-based hosts (RHEL 9 / ppc64le).
sudo cp /etc/containers/containers.conf /etc/containers/executor-containers.conf
printf '\n[network]\ndefault_subnet = "192.168.100.0/24"\n' \
| sudo tee -a /etc/containers/executor-containers.conf > /dev/null
sudo chmod 644 /etc/containers/executor-containers.conf

# Enable IP forwarding so Netavark can NAT containers through the host's
# network interface. Persist via sysctl.d so the setting survives reboots.
printf 'net.ipv4.ip_forward = 1\nnet.ipv4.conf.all.forwarding = 1\n' \
| sudo tee /etc/sysctl.d/99-podman-ip-forward.conf > /dev/null
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf.all.forwarding=1

# Ensure NAT masquerade is active for the Podman bridge subnet.
# On RHEL/firewalld systems, Netavark normally configures this, but
# 'podman system reset' can leave firewalld without the masquerade rule
# until the first container is actually created — too late for the runner
# to resolve DNS at job startup. We add the rule explicitly so it is in
# place before any job container tries to reach an external DNS server.
sudo iptables -t nat -A POSTROUTING \
-s 10.88.0.0/16 ! -d 10.88.0.0/16 -j MASQUERADE 2>/dev/null || true
# On firewalld systems (RHEL/Fedora), enable masquerade permanently so it
# survives firewalld restarts and reboots, then reload to activate immediately.
sudo firewall-cmd --permanent --add-masquerade 2>/dev/null || true
sudo firewall-cmd --reload 2>/dev/null || true

# Register runner using docker executor backed by Podman
# --docker-privileged is required for Podman: containers need CAP_SYS_ADMIN to mount /proc
sudo gitlab-runner register \
--non-interactive \
--url "{{ .RepoURL }}" \
--token "{{ .Token }}" \
--name "{{ .Name }}" \
--executor "docker" \
--docker-image "fedora:latest" \
--docker-host "unix:///run/podman/podman.sock" \
--docker-privileged
--docker-privileged \
"${_docker_dns_args[@]}" \
--docker-volumes "/etc/containers/executor-containers.conf:/etc/containers/containers.conf:ro"

{{- if not .Unsecure}}
# Create a dedicated system user for running CI jobs
Expand Down
1 change: 1 addition & 0 deletions pkg/integrations/gitlab/snippet-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ C:\GitLab-Runner\gitlab-runner.exe register `
--non-interactive `
--url "{{ .RepoURL }}" `
--token "{{ .Token }}" `
--name "{{ .Name }}" `
--executor "shell"

# Install and start as Windows service
Expand Down
5 changes: 3 additions & 2 deletions pkg/integrations/gitlab/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type GitLabRunnerArgs struct {
Arch *Arch // Target architecture
User string // OS user to run as (only used when Unsecure is true)
AuthToken string // Runner authentication token (set by Pulumi during deployment)
Unsecure bool // When false (default) a dedicated gitlab-runner system user is created; when true the runner service runs as User
Concurrent int // Maximum number of concurrent jobs (written to config.toml; 0 means leave at default of 1)
Unsecure bool // When false (default) a dedicated gitlab-runner system user is created; when true the runner service runs as User
Concurrent int // Maximum number of concurrent jobs (written to config.toml; 0 means leave at default of 1)
LogToJournald bool // When true, sets Podman log_driver=journald so CI job output is captured by systemd journal for OTel correlation
}
21 changes: 11 additions & 10 deletions pkg/integrations/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import (
)

type UserDataValues struct {
CliURL string
User string
Name string
Token string
Labels string
Port string
RepoURL string
Executor string
Unsecure bool
Concurrent int
CliURL string
User string
Name string
Token string
Labels string
Port string
RepoURL string
Executor string
Unsecure bool
Concurrent int
LogToJournald bool
}

type IntegrationConfig interface {
Expand Down
23 changes: 22 additions & 1 deletion pkg/integrations/otelcol/snippet-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,31 @@ receivers:
- type: remove
id: remove_file_name
field: attributes["log.file.name"]
- type: regex_parser
id: parse_job_id
parse_from: body
regex: '\bjob=(?P<job_id>\d+)'
on_error: send
- type: regex_parser
id: parse_runner_token
parse_from: body
regex: '\brunner=(?P<runner_token>\w+)'
on_error: send
attributes:
index: "{{.Index}}"
_sourceCategory: gitlab-runner
_sourceHost: ${env:HOSTNAME}
journald/gitlab-jobs:
operators:
- type: regex_parser
id: parse_container_name
parse_from: attributes["CONTAINER_NAME"]
regex: '^runner-(?P<runner_token>.+?)-project-(?P<project_id>\d+)-concurrent-(?P<concurrent_id>\d+)-(?P<job_id>\d+)$'
on_error: send
attributes:
index: "{{.Index}}"
_sourceCategory: gitlab-runner-jobs
_sourceHost: ${env:HOSTNAME}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
{{- end}}
processors:
filter/drop_null_bytes:
Expand Down Expand Up @@ -185,7 +206,7 @@ service:
level: "basic"
pipelines:
logs:
receivers: [filelog/syslog, filelog/secure, filelog/audit{{if .MonitorGitLabRunner}}, filelog/gitlab-runner{{end}}]
receivers: [filelog/syslog, filelog/secure, filelog/audit{{if .MonitorGitLabRunner}}, filelog/gitlab-runner, journald/gitlab-jobs{{end}}]
processors: [filter/drop_null_bytes, resource, batch]
exporters: [otlphttp]
OTELEOF
Expand Down
2 changes: 1 addition & 1 deletion pkg/manager/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func manageIntegration(c *Context, ca *ContextArgs) error {
cirrus.Init(ca.CirrusPWArgs)
}
if ca.GLRunnerArgs != nil {
ca.GLRunnerArgs.Name = c.RunID()
ca.GLRunnerArgs.Name = c.ProjectName()
gitlab.Init(ca.GLRunnerArgs)
}
return nil
Expand Down
26 changes: 16 additions & 10 deletions pkg/provider/ibmcloud/action/ibm-power/cloud-config
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,31 @@ write_files:
if mountpoint -q /home; then
mkdir -p /home/containers/storage
else
systemctl start multipathd 2>/dev/null || true
DATA_DEV=""
_attempts=0
while true; do
DATA_DEV=$(lsblk -rnpo NAME,TYPE | awk '$2=="mpath"{mpath[$1]=1} $2=="part"{p=$1; sub(/p?[0-9]+$/,"",p); has_part[p]=1} END{for(d in mpath) if(!has_part[d]&&d!~/control/) print d}' | head -1)
[ -n "$DATA_DEV" ] && break
_attempts=$((_attempts + 1))
[ "$_attempts" -ge 60 ] && break
udevadm trigger --subsystem-match=block 2>/dev/null || true
udevadm settle 2>/dev/null || true
multipathd reconfigure 2>/dev/null || true
sleep 10
done
udevadm settle 2>/dev/null || true
sleep 10
mkfs.xfs -f -K "$DATA_DEV"
UUID=$(blkid -s UUID -o value "$DATA_DEV")
mkdir -p /mnt/home-tmp
cp -a /home/. /mnt/home-tmp/
mount "$DATA_DEV" /home
cp -a /mnt/home-tmp/. /home/
rm -rf /mnt/home-tmp
echo "UUID=$UUID /home xfs defaults 0 2" >> /etc/fstab
if [ -n "$DATA_DEV" ]; then
udevadm settle 2>/dev/null || true
sleep 10
mkfs.xfs -f -K "$DATA_DEV"
UUID=$(blkid -s UUID -o value "$DATA_DEV")
mkdir -p /mnt/home-tmp
cp -a /home/. /mnt/home-tmp/
mount "$DATA_DEV" /home
cp -a /mnt/home-tmp/. /home/
rm -rf /mnt/home-tmp
echo "UUID=$UUID /home xfs defaults 0 2" >> /etc/fstab
fi
mkdir -p /home/containers/storage
fi
if ! mountpoint -q /var/lib/containers/storage; then
Expand Down
Loading