Let the user pass the framework image to use
Let's keep things simple for now. Trying to figure out the right framework image automatically will be very error prone. By making it a manual setting, we allow the user to even set it to a custom image or use one that they know it works. Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
This commit is contained in:
@@ -24,17 +24,18 @@ func NewConvertCmd() *cobra.Command {
|
||||
cmd.SilenceUsage = true
|
||||
cmd.SilenceErrors = true // Do not propagate errors down the line, we control them
|
||||
|
||||
// TODO: Check if this is really an existing dir (not a file)
|
||||
// TODO: Convert these to named arguments
|
||||
rootfsDir := args[0]
|
||||
resultPath := args[1]
|
||||
imageName := args[2]
|
||||
frameworkImage := args[3]
|
||||
|
||||
logger := v1.NewLogger()
|
||||
runner := action.RealRunner{
|
||||
Logger: logger,
|
||||
}
|
||||
|
||||
convertAction := action.NewConverterAction(rootfsDir, resultPath, imageName, runner)
|
||||
convertAction := action.NewConverterAction(rootfsDir, resultPath, frameworkImage, imageName, runner)
|
||||
err := convertAction.Run()
|
||||
if err != nil {
|
||||
logger.Errorf(err.Error())
|
||||
|
@@ -25,10 +25,22 @@ func NewDockerfileCmd() *cobra.Command {
|
||||
cmd.SilenceUsage = true
|
||||
cmd.SilenceErrors = true // Do not propagate errors down the line, we control them
|
||||
|
||||
rootfsDir, _ := cmd.Flags().GetString("rootfs-dir")
|
||||
baseImageURI, _ := cmd.Flags().GetString("base-image-uri")
|
||||
rootfsDir, err := cmd.Flags().GetString("rootfs-dir")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a := action.NewDockerfileAction(rootfsDir, baseImageURI)
|
||||
baseImageURI, err := cmd.Flags().GetString("base-image-uri")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frameworkImage, err := cmd.Flags().GetString("framework-image")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a := action.NewDockerfileAction(rootfsDir, baseImageURI, frameworkImage)
|
||||
dockerfile, err := a.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -48,4 +60,5 @@ func init() {
|
||||
rootCmd.AddCommand(c)
|
||||
c.Flags().StringP("rootfs-dir", "r", "", "the directory containing the extracted base image rootfs")
|
||||
c.Flags().StringP("base-image-uri", "i", "", "the URI of the base image")
|
||||
c.Flags().StringP("framework-image", "i", "", "the URI of the base image")
|
||||
}
|
||||
|
@@ -16,10 +16,11 @@ import (
|
||||
// The "input" of this action is a directory where the rootfs is extracted.
|
||||
// [TBD] The output is the same directory updated to be a Kairos image
|
||||
type ConverterAction struct {
|
||||
rootFSPath string
|
||||
resultPath string
|
||||
imageName string
|
||||
Runner Runner
|
||||
rootFSPath string
|
||||
resultPath string
|
||||
imageName string
|
||||
frameworkImage string
|
||||
Runner Runner
|
||||
}
|
||||
|
||||
// A runner that can shell-out to other commands but also be mocked in tests.
|
||||
@@ -37,12 +38,13 @@ func (r RealRunner) Run(command string, args ...string) ([]byte, error) {
|
||||
return cmd.CombinedOutput()
|
||||
}
|
||||
|
||||
func NewConverterAction(rootfsPath, resultPath, imageName string, runner Runner) *ConverterAction {
|
||||
func NewConverterAction(rootfsPath, resultPath, imageName, frameworkImage string, runner Runner) *ConverterAction {
|
||||
return &ConverterAction{
|
||||
rootFSPath: rootfsPath,
|
||||
resultPath: resultPath,
|
||||
imageName: imageName,
|
||||
Runner: runner,
|
||||
rootFSPath: rootfsPath,
|
||||
frameworkImage: frameworkImage,
|
||||
resultPath: resultPath,
|
||||
imageName: imageName,
|
||||
Runner: runner,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +57,7 @@ func NewConverterAction(rootfsPath, resultPath, imageName string, runner Runner)
|
||||
// E.g.
|
||||
// CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o build/enki && docker run -it -e PATH=/kaniko -v /tmp -v /home/dimitris/workspace/kairos/osbuilder/tmp/rootfs/:/context -v "$PWD/build/enki":/enki -v $PWD:/build --rm --entrypoint "/enki" gcr.io/kaniko-project/executor:latest convert /context
|
||||
func (ca *ConverterAction) Run() (err error) {
|
||||
da := NewDockerfileAction(ca.rootFSPath, "")
|
||||
da := NewDockerfileAction(ca.rootFSPath, "", ca.frameworkImage)
|
||||
dockerfile, err := da.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -23,7 +23,7 @@ var _ = Describe("ConverterAction", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
imageName = newImageName(10)
|
||||
runner = v1mock.NewFakeRunner()
|
||||
action = NewConverterAction(rootfsPath, path.Join(resultDir, "image.tar"), imageName, runner)
|
||||
action = NewConverterAction(rootfsPath, path.Join(resultDir, "image.tar"), imageName, "quay.io/kairos/framework:master_ubuntu", runner)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
|
@@ -5,21 +5,17 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ConverterAction is the action that converts a non-kairos image to a Kairos one.
|
||||
// The conversion happens in a best-effort manner. It's not guaranteed that
|
||||
// any distribution will successfully be converted to a Kairos flavor. See
|
||||
// the Kairos releases for known-to-work flavors.
|
||||
// The "input" of this action is a directory where the rootfs is extracted.
|
||||
// [TBD] The output is the same directory updated to be a Kairos image
|
||||
type DockerfileAction struct {
|
||||
rootFSPath string
|
||||
baseImageURI string
|
||||
rootFSPath string
|
||||
baseImageURI string
|
||||
frameworkImage string
|
||||
}
|
||||
|
||||
func NewDockerfileAction(rootfsPath, baseImageURI string) *DockerfileAction {
|
||||
func NewDockerfileAction(rootfsPath, baseImageURI, frameworkImage string) *DockerfileAction {
|
||||
return &DockerfileAction{
|
||||
rootFSPath: rootfsPath,
|
||||
baseImageURI: baseImageURI,
|
||||
rootFSPath: rootfsPath,
|
||||
baseImageURI: baseImageURI,
|
||||
frameworkImage: frameworkImage,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +28,8 @@ func (a *DockerfileAction) Run() (dockerfile string, err error) {
|
||||
dockerfile += a.baseImageSection()
|
||||
dockerfile += a.dnsSection()
|
||||
dockerfile += a.luetInstallSection("")
|
||||
dockerfile += a.installFrameworkSection()
|
||||
dockerfile += a.switchRootSection()
|
||||
dockerfile += a.installFrameworkSection()
|
||||
dockerfile += a.osSpecificSection()
|
||||
|
||||
return dockerfile, nil
|
||||
@@ -84,10 +80,9 @@ COPY --from=builder /rootfs/ .
|
||||
// installFrameworkSection chooses the right framework image for the current
|
||||
// base image and upacks it to the /rootfs directory
|
||||
func (a *DockerfileAction) installFrameworkSection() string {
|
||||
return `
|
||||
COPY --from=quay.io/kairos/enki /enki /enki
|
||||
RUN /bin/bash -c 'luet util unpack quay.io/kairos/framework:$(/enki find-matching-framework) /'
|
||||
`
|
||||
return fmt.Sprintf(`
|
||||
COPY --from=%s . /
|
||||
`, a.frameworkImage)
|
||||
}
|
||||
|
||||
func (a *DockerfileAction) osSpecificSection() string {
|
||||
@@ -103,5 +98,9 @@ func (a *DockerfileAction) Validate() error {
|
||||
return errors.New("exactly one of 'rootfs-dir' and 'base-image-uri' should be defined")
|
||||
}
|
||||
|
||||
if a.frameworkImage == "" {
|
||||
return errors.New("'framework-image' should be defined")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ var _ = Describe("DockerfileAction", func() {
|
||||
|
||||
When("both a rootfs dir and a base image URI are defined", func() {
|
||||
BeforeEach(func() {
|
||||
action = NewDockerfileAction("somedir", "quay.io/kairos/someimage")
|
||||
action = NewDockerfileAction("somedir", "quay.io/kairos/someimage", "quay.io/kairos/framework:master_ubuntu")
|
||||
})
|
||||
|
||||
It("returns an error", func() {
|
||||
@@ -28,7 +28,7 @@ var _ = Describe("DockerfileAction", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
rootfsPath = prepareEmptyRootfs()
|
||||
action = NewDockerfileAction(rootfsPath, "")
|
||||
action = NewDockerfileAction(rootfsPath, "", "quay.io/kairos/framework:master_ubuntu")
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
@@ -45,7 +45,7 @@ var _ = Describe("DockerfileAction", func() {
|
||||
|
||||
When("a base image uri is defined", func() {
|
||||
BeforeEach(func() {
|
||||
action = NewDockerfileAction("", "ubuntu:latest")
|
||||
action = NewDockerfileAction("", "ubuntu:latest", "quay.io/kairos/framework:master_ubuntu")
|
||||
})
|
||||
|
||||
It("starts with the provided base image", func() {
|
||||
@@ -63,7 +63,7 @@ var _ = Describe("DockerfileAction", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
rootfsPath = prepareRootfsFromImage("ubuntu:latest")
|
||||
action = NewDockerfileAction(rootfsPath, "")
|
||||
action = NewDockerfileAction(rootfsPath, "", "quay.io/kairos/framework:master_ubuntu")
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
@@ -77,7 +77,7 @@ var _ = Describe("DockerfileAction", func() {
|
||||
|
||||
When("base image URI is defined", func() {
|
||||
BeforeEach(func() {
|
||||
action = NewDockerfileAction("", "ubuntu:latest")
|
||||
action = NewDockerfileAction("", "ubuntu:latest", "quay.io/kairos/framework:master_ubuntu")
|
||||
})
|
||||
|
||||
It("adds Kairos bits", func() {
|
||||
@@ -102,5 +102,5 @@ func dockerfileMustHaveLuet(d string) {
|
||||
|
||||
func dockerfileMustInstallFramework(d string) {
|
||||
By("checking installation of framework bits")
|
||||
Expect(d).To(MatchRegexp("luet util unpack quay.io/kairos/framework"))
|
||||
Expect(d).To(MatchRegexp("COPY --from=quay.io/kairos/framework"))
|
||||
}
|
||||
|
Reference in New Issue
Block a user