Skip to content
Closed
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
59 changes: 56 additions & 3 deletions cni-plugin/deployment/scripts/install-cni.sh
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,45 @@ install_cni_conf() {
log "Created CNI config ${cni_conf_path}"
}

# Resolve a CNI config path, following symlinks and mapping absolute targets
# back into the host mount (e.g. /etc/... -> /host/etc/...).
# We need to /etc -> /host/etc when the symlink points to an absolute path as
# net.d is the container’s filesystem, not the host mount, so when cp -L follows
# that absolute target it lands on a path that doesn’t.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

... doesn't exist?

# The mapping rewrites that absolute host path to /host/etc/..., which is where
# the real file lives through the mount.
resolve_cni_config_path() {
local path=${1}
local resolved=${path}

if [ -L "${path}" ]; then
local target
target=$(readlink "${path}" || true)
if [ -n "${target}" ]; then
if [[ "${target}" = /* ]]; then
# it means the target is not empty and is an absolute path.
# It treats it as a host path.
resolved="${target}"
if [[ "${resolved}" != "${CONTAINER_MOUNT_PREFIX}"* ]]; then
local host_resolved="${CONTAINER_MOUNT_PREFIX}${resolved}"
resolved="${host_resolved}"
fi
else
# it means the target is not empty and is an relative path.
# Resolve it relative to the symlink’s directory
local base
base=$(dirname "${path}")
resolved="${base}/${target}"
fi
else
# The target was empty. It tries to fully resolve the link
resolved=$(readlink -f "${path}" 2>/dev/null || echo "${path}")
fi
resolved=$(readlink -f "${resolved}" 2>/dev/null || echo "${resolved}")
fi
echo "${resolved}"
}

# `sync()` is responsible for reacting to file system changes. It is used in
# conjunction with inotify events; `sync()` is called with the event type (which
# can be either 'CREATE', 'MOVED_TO', or 'MODIFY') and the name of the file that
Expand All @@ -260,10 +299,23 @@ sync() {
local ev=${1}
local file=${2//\/\//\/} # replace "//" with "/"

# We can't just add a * after the conflist extension otherwise there will be
# a lot of noise caused by atomic‑write temp files created by the CNI plugin.
[[ "${file}" =~ .*.(conflist|conf)$ ]] || return 0

log "Detected event: ${ev} ${file}"

local resolved_file
resolved_file=$(resolve_cni_config_path "${file}")
if [ "${resolved_file}" != "${file}" ]; then
log "File ${file} resolves to ${resolved_file}"
fi
file="${resolved_file}"
if [ ! -e "${file}" ]; then
log "Ignoring event: ${ev} ${file}; resolved path missing"
return 0
fi

# Retrieve previous SHA of detected file (if any) and compute current SHA.
local previous_sha
local current_sha
Expand Down Expand Up @@ -361,15 +413,16 @@ while true; do
done

# Append our config to any existing config file (*.conflist or *.conf)
config_files=$(find "${HOST_CNI_NET}" -maxdepth 1 -type f ! -name '*linkerd*' \( -iname '*conflist' -o -iname '*conf' \))
config_files=$(find "${HOST_CNI_NET}" -maxdepth 1 \( -type f -o -type l \) ! -name '*linkerd*' \( -iname '*conflist' -o -iname '*conf' \))
if [ -z "${config_files}" ]; then
log "No active CNI configuration files found"
else
find "${HOST_CNI_NET}" -maxdepth 1 -type f \( -iname '*conflist' -o -iname '*conf' \) -print0 |
find "${HOST_CNI_NET}" -maxdepth 1 \( -type f -o -type l \) \( -iname '*conflist' -o -iname '*conf' \) -print0 |
while read -r -d $'\0' file; do
log "Trigger CNI config detection for ${file}"
file=$(resolve_cni_config_path "${file}")
tmp_file="$(mktemp -u /tmp/linkerd-cni.patch-candidate.XXXXXX)"
cp -fp "${file}" "${tmp_file}"
cp -fpL "${file}" "${tmp_file}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

${file} shouldn't be a symlink at this point, so why the -L?

# The following will trigger the `sync()` function via filesystem event.
# This requires `monitor_cni_config()` to be up and running!
mv "${tmp_file}" "${file}" || exit_with_error 'Failed to mv files.'
Expand Down