diff --git a/cmd/build-image.go b/cmd/build-image.go index 5428c4f..79f0be2 100644 --- a/cmd/build-image.go +++ b/cmd/build-image.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "io/ioutil" "os" "path" "strings" @@ -14,13 +13,13 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - yaml "gopkg.in/yaml.v3" ) var IMAGE_CACHE string var drivers = map[string]Driver{ "libguestfs": Libguestfs{}, + "qemu": Qemu{}, } func buildImage(cmd *cobra.Command, args []string, image, outputDir string) { @@ -65,28 +64,19 @@ func buildImage(cmd *cobra.Command, args []string, image, outputDir string) { log.Fatalf("%s does not exists", image) } - tmpfile, err := ioutil.TempFile("", "konfigadm.*.yml") - if err != nil { - log.Fatalf("Cannot create tempfile %s", err) - } - cfg := GetConfig(cmd) - _, _, err = cfg.ApplyPhases() - if err != nil { - log.Fatalf("Error applying phases %s\n", err) - } - data, _ := yaml.Marshal(cfg) - - if _, err := tmpfile.Write(data); err != nil { - log.Fatalf("Error writing tmp file %s", err) - } + cfg := GetConfig(cmd, args) var driver Driver var ok bool if driver, ok = drivers[driverName]; !ok { log.Fatalf("Invalid driver name: %s ", driverName) } - driver.Build(image, tmpfile) + if !strings.HasPrefix(image, "/") { + cwd, _ := os.Getwd() + image = path.Join(cwd, image) + } + driver.Build(image, cfg) fmt.Println(image) } @@ -114,6 +104,6 @@ func init() { cwd, _ := os.Getwd() BuildImg.Flags().String("image", "", "A local or remote path to a disk image") BuildImg.Flags().Bool("list-images", false, "Print a list of available public images to use") - BuildImg.Flags().String("driver", "libguestfs", "The image build driver to use, currently only libguestfs supported") + BuildImg.Flags().String("driver", "qemu", "The image build driver to use: Supported options are: qemu,libguestfs") BuildImg.Flags().String("output-dir", cwd, "Output directory for new images") } diff --git a/pkg/build/driver.go b/pkg/build/driver.go index ee3f160..bf1096c 100644 --- a/pkg/build/driver.go +++ b/pkg/build/driver.go @@ -1,7 +1,7 @@ package build -import "os" +import "github.com/moshloop/konfigadm/pkg/types" type Driver interface { - Build(image string, config *os.File) + Build(image string, cfg *types.Config) } diff --git a/pkg/build/libguestfs.go b/pkg/build/libguestfs.go index 2190464..77a120f 100644 --- a/pkg/build/libguestfs.go +++ b/pkg/build/libguestfs.go @@ -2,17 +2,33 @@ package build import ( "fmt" + "io/ioutil" "os" "path" "github.com/mitchellh/colorstring" + "github.com/moshloop/konfigadm/pkg/types" "github.com/moshloop/konfigadm/pkg/utils" log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" ) type Libguestfs struct{} -func (l Libguestfs) Build(image string, config *os.File) { +func (l Libguestfs) Build(image string, cfg *types.Config) { + + _, _, err := cfg.ApplyPhases() + if err != nil { + log.Fatalf("Error applying phases %s\n", err) + } + data, _ := yaml.Marshal(cfg) + tmpfile, err := ioutil.TempFile("", "konfigadm.*.yml") + if err != nil { + log.Fatalf("Cannot create tempfile %s", err) + } + if _, err := tmpfile.Write(data); err != nil { + log.Fatalf("Error writing tmp file %s", err) + } os.Remove("/tmp/builder.log") os.Remove("builder.log") @@ -23,7 +39,7 @@ func (l Libguestfs) Build(image string, config *os.File) { --delete /tmp/builder.log \ --copy-in %s:/tmp \ --copy-in %s:/tmp \ - --run-command '/tmp/%s apply -vv -c %s' 1>&2`, image, konfigadmPath, config.Name(), konfigAdm, config.Name()) + --run-command '/tmp/%s apply -vv -c %s' 1>&2`, image, konfigadmPath, tmpfile.Name(), konfigAdm, tmpfile.Name()) log.Infof("Executing %s\n", colorstring.Color("[light_green]"+cmdLine)) if err := utils.Exec(cmdLine); err != nil { diff --git a/pkg/build/qemu.go b/pkg/build/qemu.go new file mode 100644 index 0000000..3147cfa --- /dev/null +++ b/pkg/build/qemu.go @@ -0,0 +1,31 @@ +package build + +import ( + "fmt" + + cloudinit "github.com/moshloop/konfigadm/pkg/cloud-init" + "github.com/moshloop/konfigadm/pkg/types" + + "github.com/mitchellh/colorstring" + "github.com/moshloop/konfigadm/pkg/utils" + log "github.com/sirupsen/logrus" +) + +type Qemu struct{} + +func (q Qemu) Build(image string, config *types.Config) { + + config.PostCommands = append(config.PostCommands, types.Command{Cmd: "cloud-init clean; shutdown -h now"}) + iso, _ := cloudinit.CreateISO("builder", config.ToCloudInit().String()) + cmdLine := fmt.Sprintf(` + kvm -M pc -m 1024 -smp 2 \ + -nographic \ + -hda %s \ + -drive "file=%s,if=virtio,format=raw" \ + -net nic -net user,hostfwd=tcp:127.0.0.1:2022-:22`, image, iso) + + log.Infof("Executing %s\n", colorstring.Color("[light_green]"+cmdLine)) + if err := utils.Exec(cmdLine); err != nil { + log.Fatalf("Failed to run: %s, %s", cmdLine, err) + } +}