+
+ // Find symlinks to arv-mounted files & dirs.
+ err = filepath.Walk(runner.HostOutputDir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if info.Mode()&os.ModeSymlink == 0 {
+ return nil
+ }
+ // read link to get container internal path
+ var tgt string
+ tgt, err = os.Readlink(path)
+ if err != nil {
+ return err
+ }
+ if !strings.HasPrefix(tgt, "/") {
+ // Link is relative, don't handle it
+ return nil
+ }
+ // go through mounts and reverse map to collection reference
+ for _, bind := range binds {
+ if tgt == bind || strings.HasPrefix(tgt, bind+"/") {
+ mnt := runner.Container.Mounts[bind]
+
+ // get path relative to bind
+ sourceSuffix := tgt[len(bind):]
+ // get path relative to output dir
+ bindSuffix := path[len(runner.HostOutputDir):]
+
+ // Copy mount and adjust the path to add path relative to the bind
+ adjustedMount := mnt
+ adjustedMount.Path = filepath.Join(adjustedMount.Path, sourceSuffix)
+
+ // get manifest text
+ var m string
+ m, err = runner.getCollectionManifestForPath(adjustedMount, bindSuffix)
+ if err != nil {
+ return err
+ }
+ manifestText = manifestText + m
+ // delete symlink so WriteTree won't try to to dereference it.
+ os.Remove(path)
+ return nil
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ return fmt.Errorf("While checking output symlinks: %v", err)
+ }
+