Skip to content

Commit dee58d4

Browse files
committed
simple build engine support for the imagebuild command
Signed-off-by: Kyle Quest <kcq.public@gmail.com>
1 parent 372ac48 commit dee58d4

File tree

6 files changed

+608
-141
lines changed

6 files changed

+608
-141
lines changed

pkg/app/master/command/imagebuild/cli.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ type CommandParams struct {
3535
BuildArgs []imagebuilder.NVParam `json:"build_args,omitempty"`
3636
Labels map[string]string `json:"labels,omitempty"`
3737
Architecture string `json:"architecture,omitempty"`
38+
BaseImage string `json:"base_image,omitempty"`
39+
BaseImageTar string `json:"base_image_tar,omitempty"`
40+
ExePath string `json:"exe_path,omitempty"`
3841
}
3942

4043
var ImageBuildFlags = useAllFlags()
@@ -69,6 +72,9 @@ var CLI = &cli.Command{
6972
ContextDir: ctx.String(FlagContextDir),
7073
Runtime: ctx.String(FlagRuntimeLoad),
7174
Architecture: ctx.String(FlagArchitecture),
75+
BaseImage: ctx.String(FlagBase),
76+
BaseImageTar: ctx.String(FlagBaseTar),
77+
ExePath: ctx.String(FlagExePath),
7278
Labels: map[string]string{},
7379
}
7480

@@ -104,6 +110,11 @@ var CLI = &cli.Command{
104110
logger.Errorf("Dockerfile not found - '%s'", cparams.Dockerfile)
105111
return command.ErrBadParamValue
106112
}
113+
case SimpleBuildEngine:
114+
if cparams.ExePath == "" && !fsutil.Exists(cparams.Dockerfile) {
115+
logger.Errorf("no exe-path and no Dockerfile - '%s'", cparams.Dockerfile)
116+
return command.ErrBadParamValue
117+
}
107118
default:
108119
fullDockerfilePath := filepath.Join(cparams.ContextDir, cparams.Dockerfile)
109120
if !fsutil.Exists(fullDockerfilePath) {

pkg/app/master/command/imagebuild/flags.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ const (
4444

4545
FlagArchitecture = "architecture"
4646
FlagArchitectureUsage = "build architecture"
47+
48+
FlagBase = "base"
49+
FlagBaseUsage = "base image to use (from selected runtime, docker by default, or pulled if not available)"
50+
51+
FlagBaseTar = "base-tar"
52+
FlagBaseTarUsage = "base image from a local tar file"
53+
54+
FlagExePath = "exe-path"
55+
FlagExePathUsage = "local (linux) executable file that will be used as the entrypoint for the new image (added to the selected base image or scratch image if no base image is provided)"
4756
)
4857

4958
const (
@@ -200,6 +209,24 @@ var Flags = map[string]cli.Flag{
200209
Usage: FlagArchitectureUsage,
201210
EnvVars: []string{"DSLIM_IMAGEBUILD_ARCH"},
202211
},
212+
FlagBase: &cli.StringFlag{
213+
Name: FlagBase,
214+
Value: "",
215+
Usage: FlagBaseUsage,
216+
EnvVars: []string{"DSLIM_IMAGEBUILD_BASE"},
217+
},
218+
FlagBaseTar: &cli.StringFlag{
219+
Name: FlagBaseTar,
220+
Value: "",
221+
Usage: FlagBaseTarUsage,
222+
EnvVars: []string{"DSLIM_IMAGEBUILD_BASE_TAR"},
223+
},
224+
FlagExePath: &cli.StringFlag{
225+
Name: FlagExePath,
226+
Value: "",
227+
Usage: FlagExePathUsage,
228+
EnvVars: []string{"DSLIM_IMAGEBUILD_EXE_PATH"},
229+
},
203230
}
204231

205232
func cflag(name string) cli.Flag {
Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,111 @@
11
package imagebuild
22

33
import (
4+
"path"
5+
"path/filepath"
6+
"strings"
7+
8+
dockerapi "github.com/fsouza/go-dockerclient"
49
log "github.com/sirupsen/logrus"
510

611
"github.com/mintoolkit/mint/pkg/app"
712
"github.com/mintoolkit/mint/pkg/app/master/command"
8-
//"github.com/mintoolkit/mint/pkg/util/jsonutil"
13+
"github.com/mintoolkit/mint/pkg/imagebuilder"
14+
"github.com/mintoolkit/mint/pkg/imagebuilder/internalbuilder"
15+
"github.com/mintoolkit/mint/pkg/util/fsutil"
16+
v "github.com/mintoolkit/mint/pkg/version"
917
)
1018

1119
// HandleSimpleEngine implements support for the simple built-in container build engine
1220
func HandleSimpleEngine(
1321
logger *log.Entry,
1422
xc *app.ExecutionContext,
1523
gparams *command.GenericParams,
16-
cparams *CommandParams) {
24+
cparams *CommandParams,
25+
client *dockerapi.Client) {
26+
//passing docker client for now (later pass a CRT client), need docker client to get to the base image...
1727
logger.Trace("HandleSimpleEngine.call")
1828
defer logger.Trace("HandleSimpleEngine.exit")
29+
30+
var localExePath string
31+
var targetExePath string
32+
if strings.Contains(cparams.ExePath, ":") {
33+
parts := strings.SplitN(cparams.ExePath, ":", 2)
34+
localExePath = parts[0]
35+
targetExePath = parts[1]
36+
} else {
37+
localExePath = cparams.ExePath
38+
targetExePath = path.Join(internalbuilder.DefaultAppDir, filepath.Base(localExePath))
39+
}
40+
41+
if !fsutil.Exists(localExePath) || !fsutil.IsRegularFile(localExePath) {
42+
xc.Out.Info("build.error",
43+
ovars{
44+
"status": "docker.engine.image.build.error",
45+
"value": "bad exe path",
46+
"exe.path": cparams.ExePath,
47+
"local.exe.path": localExePath,
48+
})
49+
50+
exitCode := 111
51+
xc.Out.State("exited",
52+
ovars{
53+
"exit.code": exitCode,
54+
"version": v.Current(),
55+
"location": fsutil.ExeDir(),
56+
})
57+
58+
xc.Exit(exitCode)
59+
}
60+
61+
doShowBuildLogs := true
62+
builder, err := internalbuilder.New(doShowBuildLogs, false, false)
63+
options := imagebuilder.SimpleBuildOptions{
64+
From: cparams.BaseImage,
65+
FromTar: cparams.BaseImageTar,
66+
Tags: []string{cparams.ImageName},
67+
Layers: []imagebuilder.LayerDataInfo{
68+
{
69+
Type: imagebuilder.FileSource,
70+
Source: cparams.ExePath,
71+
Params: &imagebuilder.DataParams{
72+
TargetPath: targetExePath,
73+
},
74+
EntrypointLayer: true,
75+
},
76+
},
77+
ImageConfig: &imagebuilder.ImageConfig{
78+
Architecture: cparams.Architecture,
79+
Config: imagebuilder.RunConfig{
80+
Entrypoint: []string{targetExePath},
81+
},
82+
},
83+
}
84+
85+
bresult, err := builder.Build(options)
86+
if err != nil {
87+
xc.Out.Info("build.error",
88+
ovars{
89+
"status": "docker.engine.image.build.error",
90+
"value": err,
91+
})
92+
93+
exitCode := 721
94+
xc.Out.State("exited",
95+
ovars{
96+
"exit.code": exitCode,
97+
"version": v.Current(),
98+
"location": fsutil.ExeDir(),
99+
})
100+
101+
xc.Exit(exitCode)
102+
}
103+
104+
xc.Out.State("docker.engine.image.build.completed")
105+
xc.Out.Info("output.image",
106+
ovars{
107+
"name": bresult.Name,
108+
"id": bresult.ID,
109+
"digest": bresult.Digest,
110+
})
19111
}

pkg/app/master/command/imagebuild/handler.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,12 @@ func OnCommand(
123123

124124
HandleBuildkitEngine(logger, xc, gparams, cparams)
125125
case SimpleBuildEngine:
126+
initDockerClient() //tmp
126127
if gparams.Debug {
127128
version.Print(xc, cmdName, logger, nil, false, gparams.InContainer, gparams.IsDSImage)
128129
}
129130

130-
HandleSimpleEngine(logger, xc, gparams, cparams)
131+
HandleSimpleEngine(logger, xc, gparams, cparams, dclient)
131132
case PodmanBuildEngine:
132133
initPodmanClient()
133134
if cparams.Runtime == PodmanRuntimeLoad {

pkg/imagebuilder/imagebuilder.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ type ImageConfig struct {
3030
OSFeatures []string `json:"os.features,omitempty"`
3131
Variant string `json:"variant,omitempty"`
3232
Config RunConfig `json:"config"`
33-
RootFS *RootFS `json:"rootfs"` //not used building images
34-
History []History `json:"history,omitempty"` //not used building images
33+
RootFS *RootFS `json:"rootfs"` //not used building images
34+
History []History `json:"history,omitempty"`
35+
AddHistory []History `json:"add_history,omitempty"` //extra field
3536
//Extra fields
3637
Container string `json:"container,omitempty"`
3738
DockerVersion string `json:"docker_version,omitempty"`
@@ -60,17 +61,24 @@ type History struct {
6061
// Note: related to pkg/docker/dockerimage/ContainerConfig
6162
// TODO: refactor into one set of common structs later
6263
type RunConfig struct {
63-
User string `json:"User,omitempty"`
64-
ExposedPorts map[string]struct{} `json:"ExposedPorts,omitempty"`
65-
Env []string `json:"Env,omitempty"`
66-
Entrypoint []string `json:"Entrypoint,omitempty"`
67-
Cmd []string `json:"Cmd,omitempty"`
68-
Volumes map[string]struct{} `json:"Volumes,omitempty"`
69-
WorkingDir string `json:"WorkingDir,omitempty"`
70-
Labels map[string]string `json:"Labels,omitempty"`
71-
StopSignal string `json:"StopSignal,omitempty"`
72-
ArgsEscaped bool `json:"ArgsEscaped,omitempty"`
73-
Healthcheck *HealthConfig `json:"Healthcheck,omitempty"`
64+
User string `json:"User,omitempty"`
65+
ExposedPorts map[string]struct{} `json:"ExposedPorts,omitempty"`
66+
AddExposedPorts map[string]struct{} `json:"AddExposedPorts,omitempty"` //extra field
67+
RemoveExposedPorts []string `json:"RemoveExposedPorts,omitempty"` //extra field
68+
Env []string `json:"Env,omitempty"`
69+
AddEnv []string `json:"AddEnv,omitempty"` //extra field
70+
Entrypoint []string `json:"Entrypoint,omitempty"`
71+
IsShellEntrypoint bool `json:"IsShellEntrypoint,omitempty"` //extra field
72+
Cmd []string `json:"Cmd,omitempty"`
73+
IsShellCmd bool `json:"IsShellCmd,omitempty"` //extra field
74+
Volumes map[string]struct{} `json:"Volumes,omitempty"`
75+
AddVolumes map[string]struct{} `json:"AddVolumes,omitempty"` //extra field
76+
WorkingDir string `json:"WorkingDir,omitempty"`
77+
Labels map[string]string `json:"Labels,omitempty"`
78+
AddLabels map[string]string `json:"AddLabels,omitempty"` //extra field
79+
StopSignal string `json:"StopSignal,omitempty"`
80+
ArgsEscaped bool `json:"ArgsEscaped,omitempty"`
81+
Healthcheck *HealthConfig `json:"Healthcheck,omitempty"`
7482
//Extra fields
7583
AttachStderr bool `json:"AttachStderr,omitempty"`
7684
AttachStdin bool `json:"AttachStdin,omitempty"`
@@ -98,10 +106,12 @@ type HealthConfig struct {
98106
}
99107

100108
type SimpleBuildOptions struct {
101-
From string
102-
Tags []string
103-
Layers []LayerDataInfo
104-
ImageConfig *ImageConfig
109+
From string
110+
FromTar string
111+
Tags []string
112+
Layers []LayerDataInfo
113+
ImageConfig *ImageConfig
114+
HideBuildHistory bool
105115

106116
/*
107117
//todo: add 'Healthcheck'

0 commit comments

Comments
 (0)