mirror of
https://github.com/kairos-io/osbuilder.git
synced 2025-08-22 17:46:15 +00:00
[WIP] Write test
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
This commit is contained in:
parent
3117e3196f
commit
459ca89d5b
@ -1,14 +1,12 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kairos-io/enki/pkg/action"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewBuildISOCmd returns a new instance of the build-iso subcommand and appends it to
|
||||
// NewConvertCmd returns a new instance of the build-iso subcommand and appends it to
|
||||
// the root command.
|
||||
func NewConvertCmd() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
@ -17,7 +15,7 @@ func NewConvertCmd() *cobra.Command {
|
||||
Long: "Convert a base image to a Kairos image\n\n" +
|
||||
"This is best effort. Enki will try to detect the distribution and add\n" +
|
||||
"the necessary bits to convert it to a Kairos image",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.ExactArgs(2),
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return CheckRoot() // TODO: Do we need root?
|
||||
},
|
||||
@ -26,13 +24,14 @@ func NewConvertCmd() *cobra.Command {
|
||||
cmd.SilenceUsage = true
|
||||
cmd.SilenceErrors = true // Do not propagate errors down the line, we control them
|
||||
|
||||
rootfsDir := args[0]
|
||||
// TODO: Check if this is really an existing dir (not a file)
|
||||
fmt.Printf("rootfsDir = %+v\n", rootfsDir)
|
||||
rootfsDir := args[0]
|
||||
resultPath := args[1]
|
||||
imageName := args[2]
|
||||
|
||||
logger := v1.NewLogger()
|
||||
|
||||
convertAction := action.NewConverterAction(rootfsDir)
|
||||
convertAction := action.NewConverterAction(rootfsDir, resultPath, imageName)
|
||||
err := convertAction.Run()
|
||||
if err != nil {
|
||||
logger.Errorf(err.Error())
|
||||
|
@ -400,14 +400,10 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
|
||||
github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
|
||||
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
@ -594,8 +590,6 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -678,8 +672,6 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -853,8 +845,6 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
|
||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
|
||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -15,11 +15,15 @@ import (
|
||||
// [TBD] The output is the same directory updated to be a Kairos image
|
||||
type ConverterAction struct {
|
||||
rootFSPath string
|
||||
resultPath string
|
||||
imageName string
|
||||
}
|
||||
|
||||
func NewConverterAction(rootfsPath string) *ConverterAction {
|
||||
func NewConverterAction(rootfsPath, resultPath, imageName string) *ConverterAction {
|
||||
return &ConverterAction{
|
||||
rootFSPath: rootfsPath,
|
||||
resultPath: resultPath,
|
||||
imageName: imageName,
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,11 +48,10 @@ func (ca *ConverterAction) Run() (err error) {
|
||||
}
|
||||
defer ca.removeDockerIgnore()
|
||||
|
||||
out, err := ca.BuildWithKaniko(dockerfile)
|
||||
out, err := ca.BuildWithKaniko(dockerfile, ca.resultPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s", err, out)
|
||||
}
|
||||
fmt.Printf("out = %+v\n", out)
|
||||
|
||||
return
|
||||
}
|
||||
@ -111,13 +114,12 @@ func (ca *ConverterAction) removeDockerIgnore() error {
|
||||
return os.RemoveAll(path.Join(ca.rootFSPath, ".dockerignore"))
|
||||
}
|
||||
|
||||
func (ca *ConverterAction) BuildWithKaniko(dockerfile string) (string, error) {
|
||||
fmt.Printf("ca.rootFSPath = %+v\n", ca.rootFSPath)
|
||||
func (ca *ConverterAction) BuildWithKaniko(dockerfile, resultPath string) (string, error) {
|
||||
cmd := exec.Command("executor",
|
||||
"--dockerfile", dockerfile,
|
||||
"--context", ca.rootFSPath,
|
||||
"--destination", "whatever",
|
||||
"--tar-path", "/build/image.tar", // TODO: Where do we write? Do we want this extracted to the rootFSPath?
|
||||
"--destination", ca.imageName, // This is the name of the image when you: cat image.tar | docker load
|
||||
"--tar-path", resultPath, // TODO: Do we want this extracted to the rootFSPath?
|
||||
"--no-push",
|
||||
)
|
||||
|
||||
|
@ -1,11 +1,89 @@
|
||||
package action_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
. "github.com/kairos-io/enki/pkg/action"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
//. "github.com/onsi/gomega"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("BuildISOAction", func() {
|
||||
var _ = FDescribe("ConverterAction", func() {
|
||||
var rootfsPath, resultDir, imageName string
|
||||
var action *ConverterAction
|
||||
|
||||
BeforeEach(func() {
|
||||
rootfsPath = prepareRootfs()
|
||||
resultDir = prepareResultDir()
|
||||
imageName = newImageName(10)
|
||||
action = NewConverterAction(rootfsPath, path.Join(resultDir, "image.tar"), imageName)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
cleanupDir(rootfsPath)
|
||||
cleanupDir(resultDir)
|
||||
removeImage(imageName)
|
||||
})
|
||||
|
||||
It("adds the framework bits", func() {
|
||||
// TODO: Run enki next to kaniko (in an image?)
|
||||
// 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
|
||||
Expect(action.Run()).ToNot(HaveOccurred())
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("cat %s/image.tar | docker load", resultDir))
|
||||
out, err := cmd.CombinedOutput()
|
||||
Expect(err).ToNot(HaveOccurred(), string(out))
|
||||
})
|
||||
})
|
||||
|
||||
func prepareRootfs() string {
|
||||
dir, err := os.MkdirTemp("", "kairos-temp")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c",
|
||||
fmt.Sprintf("docker run -v %s:/work quay.io/luet/base util unpack ubuntu:latest /work", dir))
|
||||
out, err := cmd.CombinedOutput()
|
||||
Expect(err).ToNot(HaveOccurred(), string(out))
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
func prepareResultDir() string {
|
||||
dir, err := os.MkdirTemp("", "kairos-temp")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
func newImageName(n int) string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func removeImage(image string) {
|
||||
fmt.Printf("image = %+v\n", image)
|
||||
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("docker rmi %s:latest", image))
|
||||
out, err := cmd.CombinedOutput()
|
||||
Expect(err).ToNot(HaveOccurred(), string(out))
|
||||
}
|
||||
|
||||
// Cleanup in docker to use the same permissions as those when we created.
|
||||
// This way we avoid sudo.
|
||||
func cleanupDir(path string) {
|
||||
fmt.Printf("path = %+v\n", path)
|
||||
cmd := exec.Command("/bin/sh", "-c",
|
||||
fmt.Sprintf("docker run --rm -v %[1]s:/work ubuntu /bin/bash -c 'rm -rf /work/*'", path))
|
||||
out, err := cmd.CombinedOutput()
|
||||
Expect(err).ToNot(HaveOccurred(), string(out))
|
||||
Expect(os.RemoveAll(path)).ToNot(HaveOccurred())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user