diff --git a/.dockerignore b/.dockerignore index da46e3e..471022c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,3 +6,4 @@ qemu.sh bin dist images +examples/build diff --git a/.gitignore b/.gitignore index 2e71f2e..16cde8b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ dist/ images wstation /d2vm +/examples/build diff --git a/Dockerfile b/Dockerfile index 4119a84..421032e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,7 @@ FROM ubuntu:20.04 RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ + ca-certificates \ util-linux \ udev \ parted \ diff --git a/Makefile b/Makefile index 694c584..a4451aa 100644 --- a/Makefile +++ b/Makefile @@ -91,3 +91,13 @@ build: $(BIN) bin .PHONY: release release: $(BIN) bin @VERSION=$(VERSION) IMAGE=$(DOCKER_IMAGE) goreleaser release --rm-dist --parallelism 8 + +.PHONY: examples +examples: build-dev + @mkdir -p examples/build + @for f in $$(find examples -type f -name '*Dockerfile' -maxdepth 1); do \ + echo "Building $$f"; \ + ./d2vm build -o examples/build/$$(basename $$f|cut -d'.' -f1).qcow2 -f $$f examples; \ + done + @echo "Building examples/full/Dockerfile" + @./d2vm build -o examples/build/full.qcow2 --build-arg=USER=adphi --build-arg=PASSWORD=adphi examples/full diff --git a/cmd/d2vm/build.go b/cmd/d2vm/build.go index 0e93e4c..68d3c4f 100644 --- a/cmd/d2vm/build.go +++ b/cmd/d2vm/build.go @@ -26,7 +26,6 @@ import ( "go.linka.cloud/d2vm" "go.linka.cloud/d2vm/pkg/docker" - "go.linka.cloud/d2vm/pkg/exec" ) var ( @@ -47,7 +46,6 @@ var ( if err != nil { return err } - exec.SetDebug(debug) if file == "" { file = filepath.Join(args[0], "Dockerfile") } @@ -69,7 +67,6 @@ func init() { buildCmd.Flags().StringVarP(&output, "output", "o", output, "The output image, the extension determine the image format, raw will be used if none. Supported formats: "+strings.Join(d2vm.OutputFormats(), " ")) buildCmd.Flags().StringVarP(&password, "password", "p", "root", "Root user password") buildCmd.Flags().StringVarP(&size, "size", "s", "10G", "The output image size") - buildCmd.Flags().BoolVarP(&debug, "debug", "d", false, "Enable Debug output") buildCmd.Flags().BoolVar(&force, "force", false, "Override output image") buildCmd.Flags().StringVar(&cmdLineExtra, "append-to-cmdline", "", "Extra kernel cmdline arguments to append to the generated one") buildCmd.Flags().StringVar(&networkManager, "network-manager", "", "Network manager to use for the image: none, netplan, ifupdown") diff --git a/cmd/d2vm/convert.go b/cmd/d2vm/convert.go index bfc9a03..e845136 100644 --- a/cmd/d2vm/convert.go +++ b/cmd/d2vm/convert.go @@ -26,7 +26,6 @@ import ( "go.linka.cloud/d2vm" "go.linka.cloud/d2vm/pkg/docker" - "go.linka.cloud/d2vm/pkg/exec" ) var ( @@ -56,7 +55,6 @@ var ( return fmt.Errorf("%s already exists", output) } } - exec.SetDebug(debug) if _, err := os.Stat(output); err == nil || !os.IsNotExist(err) { if !force { return fmt.Errorf("%s already exists", output) @@ -97,7 +95,6 @@ func init() { convertCmd.Flags().StringVarP(&output, "output", "o", output, "The output image, the extension determine the image format, raw will be used if none. Supported formats: "+strings.Join(d2vm.OutputFormats(), " ")) convertCmd.Flags().StringVarP(&password, "password", "p", "root", "The Root user password") convertCmd.Flags().StringVarP(&size, "size", "s", "10G", "The output image size") - convertCmd.Flags().BoolVarP(&debug, "debug", "d", false, "Enable Debug output") convertCmd.Flags().BoolVarP(&force, "force", "f", false, "Override output qcow2 image") convertCmd.Flags().StringVar(&cmdLineExtra, "append-to-cmdline", "", "Extra kernel cmdline arguments to append to the generated one") convertCmd.Flags().StringVar(&networkManager, "network-manager", "", "Network manager to use for the image: none, netplan, ifupdown") diff --git a/cmd/d2vm/main.go b/cmd/d2vm/main.go index c54fb90..e4aa414 100644 --- a/cmd/d2vm/main.go +++ b/cmd/d2vm/main.go @@ -20,9 +20,11 @@ import ( "os" "os/signal" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" "go.linka.cloud/d2vm" + "go.linka.cloud/d2vm/pkg/exec" ) var ( @@ -30,13 +32,19 @@ var ( size = "1G" password = "root" force = false - debug = false + verbose = false format = "qcow2" rootCmd = &cobra.Command{ Use: "d2vm", SilenceUsage: true, Version: d2vm.Version, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + if verbose { + logrus.SetLevel(logrus.TraceLevel) + } + exec.SetDebug(verbose) + }, } ) @@ -53,3 +61,9 @@ func main() { }() rootCmd.ExecuteContext(ctx) } + +func init() { + rootCmd.PersistentFlags().BoolVarP(&verbose, "debug", "d", false, "Enable Debug output") + rootCmd.PersistentFlags().MarkDeprecated("debug", "use -v instead") + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable Verbose output") +} diff --git a/cmd/d2vm/run.go b/cmd/d2vm/run.go index 10c62bf..e4875a1 100644 --- a/cmd/d2vm/run.go +++ b/cmd/d2vm/run.go @@ -15,7 +15,6 @@ package main import ( - "github.com/sirupsen/logrus" "github.com/spf13/cobra" "go.linka.cloud/d2vm/cmd/d2vm/run" @@ -25,11 +24,6 @@ var ( runCmd = &cobra.Command{ Use: "run", Short: "run the converted virtual machine", - PersistentPreRun: func(cmd *cobra.Command, args []string) { - if debug { - logrus.SetLevel(logrus.DebugLevel) - } - }, } ) @@ -39,5 +33,4 @@ func init() { runCmd.AddCommand(run.VboxCmd) runCmd.AddCommand(run.QemuCmd) runCmd.AddCommand(run.HetznerCmd) - runCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "Enable Debug output") } diff --git a/cmd/d2vm/run/hetzner.go b/cmd/d2vm/run/hetzner.go index 1250c2b..81757e1 100644 --- a/cmd/d2vm/run/hetzner.go +++ b/cmd/d2vm/run/hetzner.go @@ -33,9 +33,10 @@ import ( ) const ( - serverImg = "ubuntu-20.04" - vmBlockPath = "/dev/sda" - sparsecatPath = "/usr/local/bin/sparsecat" + hetznerTokenEnv = "HETZNER_TOKEN" + serverImg = "ubuntu-20.04" + vmBlockPath = "/dev/sda" + sparsecatPath = "/usr/local/bin/sparsecat" ) var ( @@ -56,7 +57,7 @@ var ( ) func init() { - HetznerCmd.Flags().StringVarP(&hetznerToken, "token", "t", "", "Hetzner Cloud API token") + HetznerCmd.Flags().StringVarP(&hetznerToken, "token", "t", "", "Hetzner Cloud API token [$"+hetznerTokenEnv+"]") HetznerCmd.Flags().StringVarP(&hetznerSSHUser, "user", "u", "root", "d2vm image ssh user") HetznerCmd.Flags().StringVarP(&hetznerSSHKeyPath, "ssh-key", "i", "", "d2vm image identity key") HetznerCmd.Flags().BoolVar(&hetznerRemove, "rm", false, "remove server when done") @@ -85,7 +86,7 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io. } defer src.Close() - c := hcloud.NewClient(hcloud.WithToken(hetznerToken)) + c := hcloud.NewClient(hcloud.WithToken(GetStringValue(hetznerTokenEnv, hetznerToken, ""))) st, _, err := c.ServerType.GetByName(ctx, hetznerVMType) if err != nil { return err @@ -205,8 +206,10 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io. logrus.Infof("%s / %d%% transfered ( %s/s)", humanize.Bytes(uint64(b)), int(float64(b)/float64(i.VirtualSize)*100), humanize.Bytes(uint64(b-last))) last = b case <-ctx.Done(): + logrus.Warnf("context cancelled") return case <-done: + logrus.Infof("transfer finished") return } } diff --git a/examples/alpine.Dockerfile b/examples/alpine.Dockerfile index 75c994e..3a72437 100644 --- a/examples/alpine.Dockerfile +++ b/examples/alpine.Dockerfile @@ -1,4 +1,5 @@ FROM alpine -RUN apk add --no-cache openssh-server && \ +RUN apk add --no-cache openrc openssh-server && \ + rc-update add sshd default && \ echo "PermitRootLogin yes" >> /etc/ssh/sshd_config diff --git a/examples/debian.Dockerfile b/examples/debian.Dockerfile index 4c1f475..74997b2 100644 --- a/examples/debian.Dockerfile +++ b/examples/debian.Dockerfile @@ -1,4 +1,5 @@ FROM debian -RUN apt update && apt install -y openssh-server && \ +RUN apt update && apt install -y openssh-server systemctl && \ + systemctl enable ssh && \ echo "PermitRootLogin yes" >> /etc/ssh/sshd_config diff --git a/examples/full/00-netconf.yaml b/examples/full/00-netconf.yaml deleted file mode 100644 index 8edbc4c..0000000 --- a/examples/full/00-netconf.yaml +++ /dev/null @@ -1,10 +0,0 @@ -network: - version: 2 - renderer: networkd - ethernets: - eth0: - dhcp4: true - nameservers: - addresses: - - 8.8.8.8 - - 8.8.4.4 diff --git a/examples/full/Dockerfile b/examples/full/Dockerfile index 76a3698..50a8843 100644 --- a/examples/full/Dockerfile +++ b/examples/full/Dockerfile @@ -3,14 +3,11 @@ FROM ubuntu # Install some system packages RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ qemu-guest-agent \ - netplan.io \ ca-certificates \ dnsutils \ sudo \ openssh-server -# Setup default network config -COPY 00-netconf.yaml /etc/netplan/ # Add a utility script to resize serial terminal COPY resize /usr/local/bin/ diff --git a/examples/ubuntu.Dockerfile b/examples/ubuntu.Dockerfile index be9568c..d7ce6c8 100644 --- a/examples/ubuntu.Dockerfile +++ b/examples/ubuntu.Dockerfile @@ -1,4 +1,5 @@ FROM ubuntu -RUN apt update && apt install -y openssh-server && \ +RUN apt update && apt install -y openssh-server systemctl && \ + systemctl enable ssh && \ echo "PermitRootLogin yes" >> /etc/ssh/sshd_config diff --git a/templates/debian.Dockerfile b/templates/debian.Dockerfile index abcdc0a..ac8366e 100644 --- a/templates/debian.Dockerfile +++ b/templates/debian.Dockerfile @@ -11,7 +11,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ systemd \ dbus \ iproute2 \ - udhcpc \ + isc-dhcp-client \ iputils-ping RUN systemctl preset-all diff --git a/templates/ubuntu.Dockerfile b/templates/ubuntu.Dockerfile index bdb61d8..ea6d37f 100644 --- a/templates/ubuntu.Dockerfile +++ b/templates/ubuntu.Dockerfile @@ -9,7 +9,7 @@ RUN apt-get update -y && \ systemd-sysv \ systemd \ dbus \ - udhcpc \ + isc-dhcp-client \ iproute2 \ iputils-ping