[WIP] Write test

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
This commit is contained in:
Dimitris Karakasilis 2023-09-06 17:46:19 +03:00
parent 3117e3196f
commit 459ca89d5b
4 changed files with 95 additions and 26 deletions

View File

@ -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())

View File

@ -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=

View File

@ -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",
)

View File

@ -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())
}