-
Notifications
You must be signed in to change notification settings - Fork 8
/
llbgen.go
92 lines (74 loc) · 3.06 KB
/
llbgen.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package genbinary
import (
"bytes"
"context"
"fmt"
"github.com/moby/buildkit/client/llb"
"namespacelabs.dev/foundation/internal/artifacts/oci"
"namespacelabs.dev/foundation/internal/build"
"namespacelabs.dev/foundation/internal/build/binary"
"namespacelabs.dev/foundation/internal/build/buildkit"
"namespacelabs.dev/foundation/internal/compute"
"namespacelabs.dev/foundation/internal/console"
"namespacelabs.dev/foundation/internal/fnerrors"
"namespacelabs.dev/foundation/internal/parsing/platform"
"namespacelabs.dev/foundation/internal/runtime/docker"
"namespacelabs.dev/foundation/internal/runtime/rtypes"
"namespacelabs.dev/foundation/schema"
"namespacelabs.dev/foundation/std/pkggraph"
"namespacelabs.dev/foundation/std/tasks"
)
func LLBBinary(packageName schema.PackageName, module *pkggraph.Module, bin build.Spec) build.Spec {
return llbBinary{packageName, module, bin}
}
type llbBinary struct {
packageName schema.PackageName
module *pkggraph.Module
bin build.Spec
}
func (l llbBinary) BuildImage(ctx context.Context, env pkggraph.SealedContext, conf build.Configuration) (compute.Computable[oci.Image], error) {
hostPlatform := docker.HostPlatform()
bin, err := l.bin.BuildImage(ctx, env, build.NewBuildTarget(&hostPlatform).WithWorkspace(l.module))
if err != nil {
return nil, err
}
action := tasks.Action("binary.llbgen").Scope(l.packageName)
if conf.TargetPlatform() != nil {
action = action.Arg("platform", platform.FormatPlatform(*conf.TargetPlatform()))
}
return compute.Map(action, compute.Inputs().Computable("bin", bin).JSON("platform", conf.TargetPlatform()), compute.Output{},
func(ctx context.Context, deps compute.Resolved) (oci.Image, error) {
binImage := compute.MustGetDepValue(deps, bin, "bin")
var targetPlatform string
if conf.TargetPlatform() != nil {
targetPlatform = platform.FormatPlatform(*conf.TargetPlatform())
}
var serializedLLB bytes.Buffer
var run rtypes.RunToolOpts
run.ImageName = fmt.Sprintf("%s/llbgen", l.packageName)
run.AllocateTTY = false
run.NoNetworking = true
run.IO.Stdout = &serializedLLB
run.IO.Stderr = console.Output(ctx, "llbgen")
run.WorkingDir = "/"
run.Image = binImage
// XXX security user id
run.Command = []string{"/" + binary.LLBGenBinaryName}
run.Env = []*schema.BinaryConfig_EnvEntry{
{Name: "TARGET_PLATFORM", Value: &schema.Resolvable{Value: targetPlatform}},
}
// XXX use buildkit to invoke.
if err := docker.Runtime().Run(ctx, run); err != nil {
return nil, fnerrors.New("failed to call llbgen :%w", err)
}
def, err := llb.ReadFrom(bytes.NewReader(serializedLLB.Bytes()))
if err != nil {
return nil, err
}
return compute.GetValue(ctx, buildkit.BuildDefinitionToImage(buildkit.DeferClient(env.Configuration(), &hostPlatform), conf, def))
}), nil
}
func (l llbBinary) PlatformIndependent() bool { return false }