Skip to content

Commit feb3ef3

Browse files
authored
Handle broken symlinks (#101)
1 parent 09b8163 commit feb3ef3

1 file changed

Lines changed: 56 additions & 4 deletions

File tree

go/cmd/ocitool/createlayer_cmd.go

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ func CreateLayerCmd(c *cli.Context) error {
9090
/* tarGid */ tarGid,
9191
/* tw */ tw,
9292
)
93-
9493
if err != nil {
9594
return err
9695
}
@@ -114,15 +113,45 @@ func CreateLayerCmd(c *cli.Context) error {
114113
return err
115114
}
116115

117-
err = tarutil.AppendFileToTarWriter(
116+
tarMode := config.mode(tarPath)
117+
118+
// Handle broken symlinks
119+
120+
hostPathIsBrokenSymlink, err := isBrokenSymlink(hostPath)
121+
if err != nil {
122+
return err
123+
}
124+
125+
if hostPathIsBrokenSymlink {
126+
tarTarget, err := os.Readlink(hostPath)
127+
if err != nil {
128+
return fmt.Errorf("error reading symlink %s: %w", hostPath, err)
129+
}
130+
131+
if err := tarutil.AppendSymlinkToTarWriter(
132+
/* tarPath */ tarPath,
133+
/* tarTarget */ tarTarget,
134+
/* tarMode */ tarMode,
135+
/* tarUid */ tarUid,
136+
/* tarGid */ tarGid,
137+
/* tw */ tw,
138+
); err != nil {
139+
return err
140+
}
141+
142+
continue
143+
}
144+
145+
// Handle all other files
146+
147+
if err := tarutil.AppendFileToTarWriter(
118148
/* hostPath */ hostPath,
119149
/* tarPath */ tarPath,
120150
/* tarMode */ config.mode(tarPath),
121151
/* tarUid */ tarUid,
122152
/* tarGid */ tarGid,
123153
/* tw */ tw,
124-
)
125-
if err != nil {
154+
); err != nil {
126155
return err
127156
}
128157
}
@@ -287,3 +316,26 @@ func (c *createLayerConfig) gid(tarPath string) (*int, error) {
287316
}
288317
return nil, nil
289318
}
319+
320+
func isBrokenSymlink(path string) (bool, error) {
321+
info, err := os.Lstat(path)
322+
if err != nil {
323+
return false, fmt.Errorf("could not lstat %s: %w", path, err)
324+
}
325+
326+
isSymlink := info.Mode()&os.ModeSymlink != 0
327+
if !isSymlink {
328+
return false, nil
329+
}
330+
331+
// TODO: What about symlinks to symlinks?
332+
_, err = os.Stat(path)
333+
if err != nil {
334+
if os.IsNotExist(err) {
335+
return true, nil
336+
}
337+
return false, fmt.Errorf("could not stat %s: %w", path, err)
338+
}
339+
340+
return false, nil
341+
}

0 commit comments

Comments
 (0)