Skip to content

Commit 0b9f8cc

Browse files
committed
Fix library paths in Apline containers
Signed-off-by: Evan Lezar <[email protected]>
1 parent 4319e43 commit 0b9f8cc

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

internal/ldconfig/ldconfig.go

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"bufio"
2222
"flag"
2323
"fmt"
24+
"io"
2425
"os"
2526
"os/exec"
2627
"path/filepath"
@@ -168,6 +169,7 @@ func (l *Ldconfig) UpdateLDCache() error {
168169
return fmt.Errorf("failed to write %s drop-in: %w", ldsoconfdFilenamePattern, err)
169170
}
170171

172+
systemSearchPaths := l.getSystemSearchPaths()
171173
// In most cases, the hook will be executing a host ldconfig that may be configured widely
172174
// differently from what the container image expects.
173175
// The common case is Debian-like (e.g. Debian, Ubuntu) vs non-Debian-like (e.g. RHEL, Fedora).
@@ -176,10 +178,15 @@ func (l *Ldconfig) UpdateLDCache() error {
176178
// paths to a drop-in conf file that is likely to be last in lexicographic order. Entries in the
177179
// top-level ld.so.conf file may be processed after this drop-in, but this hook does not modify
178180
// the top-level file if it exists.
179-
if err := createLdsoconfdFile(defaultLdsoconfdDir, ldsoconfdSystemDirsFilenamePattern, l.getSystemSearchPaths()...); err != nil {
181+
if err := createLdsoconfdFile(defaultLdsoconfdDir, ldsoconfdSystemDirsFilenamePattern, systemSearchPaths...); err != nil {
180182
return fmt.Errorf("failed to write %s drop-in: %w", ldsoconfdSystemDirsFilenamePattern, err)
181183
}
182184

185+
// Also output the folders to the alpine .path file as required.
186+
if err := createAlpinePathFileIfRequired(append(filteredDirectories, systemSearchPaths...)...); err != nil {
187+
return err
188+
}
189+
183190
return SafeExec(ldconfigPath, args, nil)
184191
}
185192

@@ -246,23 +253,30 @@ func createLdsoconfdFile(ldsoconfdDir, pattern string, dirs ...string) error {
246253
_ = configFile.Close()
247254
}()
248255

256+
if err := outputListToFile(configFile, dirs...); err != nil {
257+
return err
258+
}
259+
260+
// The created file needs to be world readable for the cases where the container is run as a non-root user.
261+
if err := configFile.Chmod(0644); err != nil {
262+
return fmt.Errorf("failed to chmod config file: %w", err)
263+
}
264+
265+
return nil
266+
}
267+
268+
func outputListToFile(w io.Writer, dirs ...string) error {
249269
added := make(map[string]bool)
250270
for _, dir := range dirs {
251271
if added[dir] {
252272
continue
253273
}
254-
_, err := fmt.Fprintf(configFile, "%s\n", dir)
274+
_, err := fmt.Fprintf(w, "%s\n", dir)
255275
if err != nil {
256276
return fmt.Errorf("failed to update config file: %w", err)
257277
}
258278
added[dir] = true
259279
}
260-
261-
// The created file needs to be world readable for the cases where the container is run as a non-root user.
262-
if err := configFile.Chmod(0644); err != nil {
263-
return fmt.Errorf("failed to chmod config file: %w", err)
264-
}
265-
266280
return nil
267281
}
268282

@@ -360,6 +374,38 @@ func processLdsoconfFile(ldsoconfFilename string) ([]string, []string, error) {
360374
return directories, includedFilenames, nil
361375
}
362376

377+
func createAlpinePathFileIfRequired(dirs ...string) error {
378+
if !isAlpine() {
379+
return nil
380+
}
381+
382+
var pathFileName string
383+
switch runtime.GOARCH {
384+
case "amd64":
385+
pathFileName = "/etc/ld-musl-x86_64.path"
386+
case "arm64":
387+
pathFileName = "/etc/ld-musl-aarch64.path"
388+
}
389+
390+
pathFile, err := os.OpenFile(pathFileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
391+
if err != nil {
392+
return fmt.Errorf("could not open .path file: %w", err)
393+
}
394+
defer func() {
395+
_ = pathFile.Close()
396+
}()
397+
398+
return outputListToFile(pathFile, dirs...)
399+
}
400+
401+
func isAlpine() bool {
402+
info, err := os.Stat("/etc/alpine-release")
403+
if err != nil {
404+
return false
405+
}
406+
return !info.IsDir()
407+
}
408+
363409
// isDebianLike returns true if a Debian-like distribution is detected.
364410
// Debian-like distributions include Debian and Ubuntu, whereas non-Debian-like
365411
// distributions include RHEL and Fedora.

0 commit comments

Comments
 (0)