2
0
mirror of https://github.com/linka-cloud/d2vm.git synced 2025-06-28 08:02:26 +00:00

improved commands output: add --time format option and color output

Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
This commit is contained in:
2022-09-09 13:22:04 +02:00
parent 77eac66d01
commit 9893c8a95a
7 changed files with 106 additions and 23 deletions

View File

@ -31,7 +31,7 @@ import (
var (
file = "Dockerfile"
tag = uuid.New().String()
tag = "d2vm-"+uuid.New().String()
networkManager string
buildArgs []string
buildCmd = &cobra.Command{

View File

@ -15,11 +15,15 @@
package main
import (
"bytes"
"context"
"fmt"
"os"
"os/signal"
"strings"
"time"
"github.com/fatih/color"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@ -28,18 +32,26 @@ import (
)
var (
output = "disk0.qcow2"
size = "1G"
password = "root"
force = false
verbose = false
format = "qcow2"
output = "disk0.qcow2"
size = "1G"
password = "root"
force = false
verbose = false
timeFormat = ""
format = "qcow2"
rootCmd = &cobra.Command{
Use: "d2vm",
SilenceUsage: true,
Version: d2vm.Version,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
switch timeFormat {
case "full", "f":
case "relative", "rel", "r":
case "none", "":
default:
logrus.Fatalf("invalid time format: %s. Valid format: 'relative', 'full'", timeFormat)
}
if verbose {
logrus.SetLevel(logrus.TraceLevel)
}
@ -66,4 +78,53 @@ 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")
rootCmd.PersistentFlags().StringVarP(&timeFormat, "time", "t", "none", "Enable formated timed output, valide formats: 'relative (rel | r)', 'full (f)'")
color.NoColor = false
logrus.StandardLogger().Formatter = &logfmtFormatter{start: time.Now()}
}
const (
red = 31
yellow = 33
blue = 36
gray = 90
)
type logfmtFormatter struct {
start time.Time
}
func (f *logfmtFormatter) Format(entry *logrus.Entry) ([]byte, error) {
var b bytes.Buffer
var c *color.Color
switch entry.Level {
case logrus.DebugLevel, logrus.TraceLevel:
c = color.New(gray)
// case logrus.InfoLevel:
// c = color.New(blue)
case logrus.WarnLevel:
c = color.New(yellow)
case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
c = color.New(red)
default:
c = color.New(color.FgWhite)
}
msg := entry.Message
if len(entry.Message) > 0 && entry.Level < logrus.DebugLevel {
msg = strings.ToTitle(string(msg[0])) + msg[1:]
}
var err error
switch timeFormat {
case "full", "f":
_, err = c.Fprintf(&b, "[%s] %s\n", entry.Time.Format("2006-01-02 15:04:05"), entry.Message)
case "relative", "rel", "r":
_, err = c.Fprintf(&b, "[%5v] %s\n", entry.Time.Sub(f.start).Truncate(time.Second).String(), msg)
default:
_, err = c.Fprintln(&b, msg)
}
if err != nil {
return nil, err
}
return b.Bytes(), nil
}

View File

@ -24,6 +24,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/dustin/go-humanize"
@ -62,7 +63,7 @@ var (
)
func init() {
HetznerCmd.Flags().StringVarP(&hetznerToken, "token", "t", "", "Hetzner Cloud API token [$"+hetznerTokenEnv+"]")
HetznerCmd.Flags().StringVar(&hetznerToken, "token", "", "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")
@ -175,6 +176,7 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
return err
}
f, err := sftpc.Create(sparsecatPath)
logrus.Debugf("creating sparsecat on remote host")
if err != nil {
return err
}
@ -197,7 +199,9 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
}
defer s.Close()
logrus.Infof("installing cloud-guest-utils on rescue server")
if b, err := s.CombinedOutput("apt update && apt install -y cloud-guest-utils"); err != nil {
cmd := "apt update && apt install -y cloud-guest-utils"
logrus.Debugf("$ %s", cmd)
if b, err := s.CombinedOutput(cmd); err != nil {
return fmt.Errorf("%v: %s", err, string(b))
}
return nil
@ -245,8 +249,11 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
} else {
cmd = fmt.Sprintf("dd of=%s", vmBlockPath)
}
logrus.Debugf("$ %s", cmd)
if b, err := wses.CombinedOutput(cmd); err != nil {
return fmt.Errorf("%v: %s", err, string(b))
} else {
logrus.Debugf(string(b))
}
return nil
}()
@ -267,8 +274,12 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
}
defer gses.Close()
logrus.Infof("resizing disk partition")
if b, err := gses.CombinedOutput(fmt.Sprintf("growpart %s 1", vmBlockPath)); err != nil {
cmd := fmt.Sprintf("growpart %s 1", vmBlockPath)
logrus.Debugf("$ %s", cmd)
if b, err := gses.CombinedOutput(cmd); err != nil {
return fmt.Errorf("%v: %s", err, string(b))
} else {
logrus.Debugf(string(b))
}
eses, err := sc.NewSession()
if err != nil {
@ -276,7 +287,9 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
}
defer eses.Close()
logrus.Infof("extending partition file system")
if b, err := eses.CombinedOutput(fmt.Sprintf("resize2fs %s1", vmBlockPath)); err != nil {
cmd = fmt.Sprintf("resize2fs %s1", vmBlockPath)
logrus.Debugf("$ %s", cmd)
if b, err := eses.CombinedOutput(cmd); err != nil {
return fmt.Errorf("%v: %s", err, string(b))
}
logrus.Infof("rebooting server")
@ -314,11 +327,12 @@ wait:
args = append(args, "-i", hetznerSSHKeyPath)
}
args = append(args, fmt.Sprintf("%s@%s", hetznerSSHUser, sres.Server.PublicNet.IPv4.IP.String()))
cmd := exec.CommandContext(ctx, "ssh", args...)
cmd.Stdin = stdin
cmd.Stderr = stderr
cmd.Stdout = stdout
if err := cmd.Run(); err != nil {
logrus.Debugf("$ ssh %s", strings.Join(args, " "))
sshCmd := exec.CommandContext(ctx, "ssh", args...)
sshCmd.Stdin = stdin
sshCmd.Stderr = stderr
sshCmd.Stdout = stdout
if err := sshCmd.Run(); err != nil {
return err
}
return nil