Skip to content

Commit

Permalink
Move symlinks setup to shared helper
Browse files Browse the repository at this point in the history
This refactors how windowscross and mariner2 interact with symlinks and
adds actual symlinking to a shared helper so other targets can use it.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
  • Loading branch information
cpuguy83 committed May 1, 2024
1 parent fe40cca commit 70d2066
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 61 deletions.
45 changes: 2 additions & 43 deletions frontend/mariner2/handle_container.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package mariner2

import (
"bytes"
"context"
"fmt"
"path/filepath"
Expand Down Expand Up @@ -143,51 +142,11 @@ rm -rf ` + rpmdbDir + `
// The return value is the state representing the contents of the mounted directory after the commands are run
rootfs := worker.AddMount(workPath, baseImg)

if post := getImagePostInstall(spec, target); post != nil && len(post.Symlinks) > 0 {
if post := spec.GetImagePost(target); post != nil && len(post.Symlinks) > 0 {
rootfs = worker.
Run(dalec.WithConstraints(opts...), addImagePost(post, workPath)).
Run(dalec.WithConstraints(opts...), dalec.InstallPostSymlinks(post, workPath)).
AddMount(workPath, rootfs)
}

return rootfs, nil
}

func getImagePostInstall(spec *dalec.Spec, targetKey string) *dalec.PostInstall {
tgt, ok := spec.Targets[targetKey]
if ok && tgt.Image != nil && tgt.Image.Post != nil {
return tgt.Image.Post
}

if spec.Image == nil {
return nil
}
return spec.Image.Post
}

func addImagePost(post *dalec.PostInstall, rootfsPath string) llb.RunOption {
return runOptionFunc(func(ei *llb.ExecInfo) {
if post == nil {
return
}

if len(post.Symlinks) == 0 {
return
}

buf := bytes.NewBuffer(nil)
buf.WriteString("set -ex\n")
fmt.Fprintf(buf, "cd %q\n", rootfsPath)

for src, tgt := range post.Symlinks {
fmt.Fprintf(buf, "ln -s %q %q\n", src, filepath.Join(rootfsPath, tgt.Path))
}
shArgs(buf.String()).SetRunOption(ei)
dalec.ProgressGroup("Add post-install symlinks").SetRunOption(ei)
})
}

type runOptionFunc func(*llb.ExecInfo)

func (f runOptionFunc) SetRunOption(ei *llb.ExecInfo) {
f(ei)
}
9 changes: 7 additions & 2 deletions frontend/windows/handle_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func handleContainer(ctx context.Context, client gwclient.Client) (*gwclient.Res

out := baseImage.
File(llb.Copy(bin, "/", windowsSystemDir)).
With(copySymlinks(spec.GetSymlinks(targetKey)))
With(copySymlinks(spec.GetImagePost(targetKey)))

def, err := out.Marshal(ctx)
if err != nil {
Expand All @@ -95,8 +95,13 @@ func handleContainer(ctx context.Context, client gwclient.Client) (*gwclient.Res
})
}

func copySymlinks(lm map[string]dalec.SymlinkTarget) llb.StateOption {
func copySymlinks(post *dalec.PostInstall) llb.StateOption {
return func(s llb.State) llb.State {
if post == nil {
return s
}

lm := post.Symlinks
if len(lm) == 0 {
return s
}
Expand Down
58 changes: 43 additions & 15 deletions helpers.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package dalec

import (
"bytes"
"encoding/json"
"fmt"
"path"
"path/filepath"
"sort"
"sync/atomic"

Expand Down Expand Up @@ -304,28 +307,53 @@ func (s *Spec) GetBuildDeps(targetKey string) []string {

}

func (s *Spec) GetSymlinks(target string) map[string]SymlinkTarget {
lm := make(map[string]SymlinkTarget)

if s.Image != nil && s.Image.Post != nil && s.Image.Post.Symlinks != nil {
for k, v := range s.Image.Post.Symlinks {
lm[k] = v
func (s *Spec) GetImagePost(target string) *PostInstall {
img := s.Targets[target].Image
if img != nil {
if img.Post != nil {
return img.Post
}
}

tgt, ok := s.Targets[target]
if !ok {
return lm
if s.Image != nil {
return s.Image.Post
}

if tgt.Image != nil && tgt.Image.Post != nil && tgt.Image.Post.Symlinks != nil {
for k, v := range tgt.Image.Post.Symlinks {
// target-specific values replace the ones in the spec toplevel
lm[k] = v
return nil
}

// ShArgs returns a RunOption that runs the given command in a shell.
func ShArgs(args string) llb.RunOption {
return llb.Args(append([]string{"sh", "-c"}, args))
}

// InstallPostSymlinks returns a RunOption that adds symlinks defined in the [PostInstall] underneath the provided rootfs path.
func InstallPostSymlinks(post *PostInstall, rootfsPath string) llb.RunOption {
return runOptionFunc(func(ei *llb.ExecInfo) {
if post == nil {
return
}
}

return lm
if len(post.Symlinks) == 0 {
return
}

llb.Dir(rootfsPath).SetRunOption(ei)

buf := bytes.NewBuffer(nil)
buf.WriteString("set -ex\n")

for src, tgt := range post.Symlinks {
fmt.Fprintf(buf, "ln -s %q %q\n", src, filepath.Join(rootfsPath, tgt.Path))
}

const name = "tmp.dalec.symlink.sh"
script := llb.Scratch().File(llb.Mkfile(name, 0o400, buf.Bytes()))

llb.AddMount(name, script, llb.SourcePath(name)).SetRunOption(ei)
llb.Args([]string{"/bin/sh", name}).SetRunOption(ei)
ProgressGroup("Add post-install symlinks").SetRunOption(ei)
})
}

func (s *Spec) GetSigner(targetKey string) (*Frontend, bool) {
Expand Down
3 changes: 2 additions & 1 deletion test/windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ echo "$BAR" > bar.txt
return nil, err
}

for srcPath, l := range spec.GetSymlinks("windowscross") {
post := spec.GetImagePost("windowscross")
for srcPath, l := range post.Symlinks {
b1, err := ref.ReadFile(ctx, gwclient.ReadRequest{
Filename: srcPath,
})
Expand Down

0 comments on commit 70d2066

Please sign in to comment.