Implements per-test logging to the current working directory
This commit is contained in:
parent
8922b3e548
commit
4f80122039
19
container.go
19
container.go
@ -15,6 +15,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/config"
|
"code.dumpstack.io/tools/out-of-tree/config"
|
||||||
@ -112,18 +113,27 @@ func listContainerImages() (diis []containerImageInfo, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type container struct {
|
type container struct {
|
||||||
name string
|
name string
|
||||||
|
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
|
||||||
Volumes struct {
|
Volumes struct {
|
||||||
LibModules string
|
LibModules string
|
||||||
UsrSrc string
|
UsrSrc string
|
||||||
Boot string
|
Boot string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional arguments
|
// Additional arguments
|
||||||
Args []string
|
Args []string
|
||||||
|
|
||||||
|
Log zerolog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContainer(name string, timeout time.Duration) (c container, err error) {
|
func NewContainer(name string, timeout time.Duration) (c container, err error) {
|
||||||
|
c.Log = log.With().
|
||||||
|
Str("container", name).
|
||||||
|
Logger()
|
||||||
|
|
||||||
c.name = name
|
c.name = name
|
||||||
c.timeout = timeout
|
c.timeout = timeout
|
||||||
|
|
||||||
@ -153,7 +163,7 @@ func (c container) Build(imagePath string) (output string, err error) {
|
|||||||
|
|
||||||
cmd := exec.Command(containerRuntime, args...)
|
cmd := exec.Command(containerRuntime, args...)
|
||||||
|
|
||||||
flog := log.With().
|
flog := c.Log.With().
|
||||||
Str("command", fmt.Sprintf("%v", cmd)).
|
Str("command", fmt.Sprintf("%v", cmd)).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
@ -182,8 +192,7 @@ func (c container) Build(imagePath string) (output string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c container) Run(workdir string, command string) (output string, err error) {
|
func (c container) Run(workdir string, command string) (output string, err error) {
|
||||||
flog := log.With().
|
flog := c.Log.With().
|
||||||
Str("container", c.name).
|
|
||||||
Str("workdir", workdir).
|
Str("workdir", workdir).
|
||||||
Str("command", command).
|
Str("command", command).
|
||||||
Logger()
|
Logger()
|
||||||
@ -212,7 +221,7 @@ func (c container) Run(workdir string, command string) (output string, err error
|
|||||||
|
|
||||||
cmd := exec.Command(containerRuntime, args...)
|
cmd := exec.Command(containerRuntime, args...)
|
||||||
|
|
||||||
log.Debug().Msgf("%v", cmd)
|
flog.Debug().Msgf("%v", cmd)
|
||||||
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
2
debug.go
2
debug.go
@ -178,7 +178,7 @@ func (cmd *DebugCmd) Run(g *Globals) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buildDir, outFile, output, err = build(tmp, ka, ki, g.Config.Docker.Timeout.Duration)
|
buildDir, outFile, output, err = build(log.Logger, tmp, ka, ki, g.Config.Docker.Timeout.Duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err, output)
|
log.Print(err, output)
|
||||||
return
|
return
|
||||||
|
33
main.go
33
main.go
@ -94,6 +94,10 @@ func (lw *LevelWriter) WriteLevel(l zerolog.Level, p []byte) (n int, err error)
|
|||||||
|
|
||||||
var tempDirBase string
|
var tempDirBase string
|
||||||
|
|
||||||
|
var consoleWriter, fileWriter LevelWriter
|
||||||
|
|
||||||
|
var loglevel zerolog.Level
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
@ -110,7 +114,6 @@ func main() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
var loglevel zerolog.Level
|
|
||||||
switch cli.LogLevel {
|
switch cli.LogLevel {
|
||||||
case "trace":
|
case "trace":
|
||||||
loglevel = zerolog.TraceLevel
|
loglevel = zerolog.TraceLevel
|
||||||
@ -132,19 +135,23 @@ func main() {
|
|||||||
tempDirBase = usr.HomeDir + "/.out-of-tree/tmp/"
|
tempDirBase = usr.HomeDir + "/.out-of-tree/tmp/"
|
||||||
os.MkdirAll(tempDirBase, os.ModePerm)
|
os.MkdirAll(tempDirBase, os.ModePerm)
|
||||||
|
|
||||||
|
consoleWriter = LevelWriter{Writer: zerolog.NewConsoleWriter(
|
||||||
|
func(w *zerolog.ConsoleWriter) {
|
||||||
|
w.Out = os.Stderr
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Level: loglevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
fileWriter = LevelWriter{Writer: &lumberjack.Logger{
|
||||||
|
Filename: usr.HomeDir + "/.out-of-tree/logs/out-of-tree.log",
|
||||||
|
},
|
||||||
|
Level: zerolog.TraceLevel,
|
||||||
|
}
|
||||||
|
|
||||||
log.Logger = log.Output(zerolog.MultiLevelWriter(
|
log.Logger = log.Output(zerolog.MultiLevelWriter(
|
||||||
&LevelWriter{Writer: zerolog.NewConsoleWriter(
|
&consoleWriter,
|
||||||
func(w *zerolog.ConsoleWriter) {
|
&fileWriter,
|
||||||
w.Out = os.Stderr
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Level: loglevel,
|
|
||||||
},
|
|
||||||
&LevelWriter{Writer: &lumberjack.Logger{
|
|
||||||
Filename: usr.HomeDir + "/.out-of-tree/logs/out-of-tree.log",
|
|
||||||
},
|
|
||||||
Level: zerolog.TraceLevel,
|
|
||||||
},
|
|
||||||
))
|
))
|
||||||
|
|
||||||
log.Trace().Msg("start out-of-tree")
|
log.Trace().Msg("start out-of-tree")
|
||||||
|
69
pew.go
69
pew.go
@ -117,7 +117,7 @@ func (cmd *PewCmd) Run(g *Globals) (err error) {
|
|||||||
if cmd.Tag == "" {
|
if cmd.Tag == "" {
|
||||||
cmd.Tag = fmt.Sprintf("%d", time.Now().Unix())
|
cmd.Tag = fmt.Sprintf("%d", time.Now().Unix())
|
||||||
}
|
}
|
||||||
log.Info().Str("tag", cmd.Tag).Msg("log")
|
log.Info().Str("tag", cmd.Tag).Msg("")
|
||||||
|
|
||||||
err = cmd.performCI(ka)
|
err = cmd.performCI(ka)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -227,8 +227,9 @@ func applyPatches(src string, ka config.Artifact) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(tmp string, ka config.Artifact, ki config.KernelInfo,
|
func build(flog zerolog.Logger, tmp string, ka config.Artifact,
|
||||||
dockerTimeout time.Duration) (outdir, outpath, output string, err error) {
|
ki config.KernelInfo, dockerTimeout time.Duration) (
|
||||||
|
outdir, outpath, output string, err error) {
|
||||||
|
|
||||||
target := fmt.Sprintf("%d_%s", rand.Int(), ki.KernelRelease)
|
target := fmt.Sprintf("%d_%s", rand.Int(), ki.KernelRelease)
|
||||||
|
|
||||||
@ -262,6 +263,7 @@ func build(tmp string, ka config.Artifact, ki config.KernelInfo,
|
|||||||
if ki.ContainerName != "" {
|
if ki.ContainerName != "" {
|
||||||
var c container
|
var c container
|
||||||
c, err = NewContainer(ki.ContainerName, dockerTimeout)
|
c, err = NewContainer(ki.ContainerName, dockerTimeout)
|
||||||
|
c.Log = flog
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("container creation failure")
|
log.Fatal().Err(err).Msg("container creation failure")
|
||||||
}
|
}
|
||||||
@ -375,24 +377,19 @@ func copyFile(sourcePath, destinationPath string) (err error) {
|
|||||||
func dumpResult(q *qemu.System, ka config.Artifact, ki config.KernelInfo,
|
func dumpResult(q *qemu.System, ka config.Artifact, ki config.KernelInfo,
|
||||||
res *phasesResult, dist, tag, binary string, db *sql.DB) {
|
res *phasesResult, dist, tag, binary string, db *sql.DB) {
|
||||||
|
|
||||||
// TODO merge (problem is it's not 100% same) with log.go:logLogEntry
|
|
||||||
|
|
||||||
distroInfo := fmt.Sprintf("%s-%s {%s}", ki.DistroType,
|
|
||||||
ki.DistroRelease, ki.KernelRelease)
|
|
||||||
|
|
||||||
colored := ""
|
colored := ""
|
||||||
switch ka.Type {
|
switch ka.Type {
|
||||||
case config.KernelExploit:
|
case config.KernelExploit:
|
||||||
colored = aurora.Sprintf("[*] %40s: %s %s", distroInfo,
|
colored = aurora.Sprintf("%s %s",
|
||||||
genOkFail("BUILD", res.Build.Ok),
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
genOkFail("LPE", res.Test.Ok))
|
genOkFail("LPE", res.Test.Ok))
|
||||||
case config.KernelModule:
|
case config.KernelModule:
|
||||||
colored = aurora.Sprintf("[*] %40s: %s %s %s", distroInfo,
|
colored = aurora.Sprintf("%s %s %s",
|
||||||
genOkFail("BUILD", res.Build.Ok),
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
genOkFail("INSMOD", res.Run.Ok),
|
genOkFail("INSMOD", res.Run.Ok),
|
||||||
genOkFail("TEST", res.Test.Ok))
|
genOkFail("TEST", res.Test.Ok))
|
||||||
case config.Script:
|
case config.Script:
|
||||||
colored = aurora.Sprintf("[*] %40s: %s", distroInfo,
|
colored = aurora.Sprintf("%s",
|
||||||
genOkFail("", res.Test.Ok))
|
genOkFail("", res.Test.Ok))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,14 +401,14 @@ func dumpResult(q *qemu.System, ka config.Artifact, ki config.KernelInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if additional != "" {
|
if additional != "" {
|
||||||
fmt.Println(colored, additional)
|
q.Log.Info().Msgf("%v %v", colored, additional)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(colored)
|
q.Log.Info().Msgf("%v", colored)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := addToLog(db, q, ka, ki, res, tag)
|
err := addToLog(db, q, ka, ki, res, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msgf("[db] addToLog (%v)", ka)
|
q.Log.Warn().Err(err).Msgf("[db] addToLog (%v)", ka)
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary == "" && dist != pathDevNull {
|
if binary == "" && dist != pathDevNull {
|
||||||
@ -549,7 +546,38 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
|
|
||||||
defer swg.Done()
|
defer swg.Done()
|
||||||
|
|
||||||
slog := log.With().
|
logdir := "logs/" + cmd.Tag
|
||||||
|
err := os.MkdirAll(logdir, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("mkdir %s", logdir)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logfile := fmt.Sprintf("logs/%s/%s-%s-%s.log",
|
||||||
|
cmd.Tag,
|
||||||
|
ki.DistroType.String(),
|
||||||
|
ki.DistroRelease,
|
||||||
|
ki.KernelRelease,
|
||||||
|
)
|
||||||
|
f, err := os.Create(logfile)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("create %s", logfile)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
slog := zerolog.New(zerolog.MultiLevelWriter(
|
||||||
|
&consoleWriter,
|
||||||
|
&fileWriter,
|
||||||
|
&zerolog.ConsoleWriter{Out: f},
|
||||||
|
))
|
||||||
|
|
||||||
|
switch loglevel {
|
||||||
|
case zerolog.TraceLevel, zerolog.DebugLevel:
|
||||||
|
slog = slog.With().Caller().Logger()
|
||||||
|
}
|
||||||
|
|
||||||
|
slog = slog.With().Timestamp().
|
||||||
Str("distro_type", ki.DistroType.String()).
|
Str("distro_type", ki.DistroType.String()).
|
||||||
Str("distro_release", ki.DistroRelease).
|
Str("distro_release", ki.DistroRelease).
|
||||||
Str("kernel", ki.KernelRelease).
|
Str("kernel", ki.KernelRelease).
|
||||||
@ -563,6 +591,8 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
slog.Error().Err(err).Msg("qemu init")
|
slog.Error().Err(err).Msg("qemu init")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
q.Log = slog
|
||||||
|
|
||||||
q.Timeout = cmd.QemuTimeout
|
q.Timeout = cmd.QemuTimeout
|
||||||
|
|
||||||
if ka.Qemu.Timeout.Duration != 0 {
|
if ka.Qemu.Timeout.Duration != 0 {
|
||||||
@ -615,7 +645,7 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
// TODO: build should return structure
|
// TODO: build should return structure
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
||||||
build(tmp, ka, ki, cmd.DockerTimeout)
|
build(slog, tmp, ka, ki, cmd.DockerTimeout)
|
||||||
slog.Debug().Str("duration", time.Now().Sub(start).String()).
|
slog.Debug().Str("duration", time.Now().Sub(start).String()).
|
||||||
Msg("build done")
|
Msg("build done")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -631,7 +661,10 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
if cmd.Test == "" {
|
if cmd.Test == "" {
|
||||||
cmd.Test = result.BuildArtifact + "_test"
|
cmd.Test = result.BuildArtifact + "_test"
|
||||||
if !exists(cmd.Test) {
|
if !exists(cmd.Test) {
|
||||||
|
slog.Debug().Msgf("%s does not exist", cmd.Test)
|
||||||
cmd.Test = tmp + "/source/" + "test.sh"
|
cmd.Test = tmp + "/source/" + "test.sh"
|
||||||
|
} else {
|
||||||
|
slog.Debug().Msgf("%s exist", cmd.Test)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,7 +700,7 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
copyArtifactAndTest(slog, q, ka, &result, remoteTest)
|
copyArtifactAndTest(slog, q, ka, &result, remoteTest)
|
||||||
slog.Debug().Str("duration", time.Now().Sub(start).String()).
|
slog.Debug().Str("duration", time.Now().Sub(start).String()).
|
||||||
Msg("test completed")
|
Msgf("test completed (success: %v)", result.Test.Ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shuffleKernels(a []config.KernelInfo) []config.KernelInfo {
|
func shuffleKernels(a []config.KernelInfo) []config.KernelInfo {
|
||||||
@ -723,10 +756,8 @@ func (cmd PewCmd) performCI(ka config.Artifact) (err error) {
|
|||||||
|
|
||||||
func exists(path string) bool {
|
func exists(path string) bool {
|
||||||
if _, err := os.Stat(path); err != nil {
|
if _, err := os.Stat(path); err != nil {
|
||||||
log.Debug().Msgf("%s does not exist", path)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
log.Debug().Msgf("%s exist", path)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ func buildPreload(workPath, tmp string, ki config.KernelInfo,
|
|||||||
dockerTimeout = ka.Docker.Timeout.Duration
|
dockerTimeout = ka.Docker.Timeout.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
_, artifact, _, err = build(tmp, ka, ki, dockerTimeout)
|
_, artifact, _, err = build(log.Logger, tmp, ka, ki, dockerTimeout)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ type System struct {
|
|||||||
// accessible after qemu is closed
|
// accessible after qemu is closed
|
||||||
exitErr error
|
exitErr error
|
||||||
|
|
||||||
log zerolog.Logger
|
Log zerolog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSystem constructor
|
// NewSystem constructor
|
||||||
func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error) {
|
func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error) {
|
||||||
q = &System{}
|
q = &System{}
|
||||||
q.log = log.With().
|
q.Log = log.With().
|
||||||
Str("kernel", kernel.KernelPath).
|
Str("kernel", kernel.KernelPath).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ func (q *System) panicWatcher() {
|
|||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
if strings.Contains(q.Stdout, "Kernel panic") {
|
if strings.Contains(q.Stdout, "Kernel panic") {
|
||||||
q.KernelPanic = true
|
q.KernelPanic = true
|
||||||
q.log.Debug().Msg("kernel panic")
|
q.Log.Debug().Msg("kernel panic")
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
// There is no reason to stay alive after kernel panic
|
// There is no reason to stay alive after kernel panic
|
||||||
q.Stop()
|
q.Stop()
|
||||||
@ -261,7 +261,7 @@ func (q *System) Start() (err error) {
|
|||||||
rand.Seed(time.Now().UnixNano()) // Are you sure?
|
rand.Seed(time.Now().UnixNano()) // Are you sure?
|
||||||
|
|
||||||
q.cmd = exec.Command(q.Executable(), q.Args()...)
|
q.cmd = exec.Command(q.Executable(), q.Args()...)
|
||||||
q.log.Debug().Msgf("%v", q.cmd)
|
q.Log.Debug().Msgf("%v", q.cmd)
|
||||||
|
|
||||||
if q.pipe.stdin, err = q.cmd.StdinPipe(); err != nil {
|
if q.pipe.stdin, err = q.cmd.StdinPipe(); err != nil {
|
||||||
return
|
return
|
||||||
@ -285,7 +285,7 @@ func (q *System) Start() (err error) {
|
|||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := scanner.Text()
|
||||||
q.Stdout += m + "\n"
|
q.Stdout += m + "\n"
|
||||||
q.log.Trace().Str("stdout", m).Msg("")
|
q.Log.Trace().Str("stdout", m).Msg("qemu")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ func (q *System) Start() (err error) {
|
|||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := scanner.Text()
|
||||||
q.Stderr += m + "\n"
|
q.Stderr += m + "\n"
|
||||||
q.log.Trace().Str("stderr", m).Msg("")
|
q.Log.Trace().Str("stderr", m).Msg("qemu")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -361,13 +361,11 @@ func (q System) ssh(user string) (client *ssh.Client, err error) {
|
|||||||
|
|
||||||
// Command executes shell commands on qemu system
|
// Command executes shell commands on qemu system
|
||||||
func (q System) Command(user, cmd string) (output string, err error) {
|
func (q System) Command(user, cmd string) (output string, err error) {
|
||||||
flog := log.With().
|
q.Log.With().Str("kernel", q.kernel.KernelPath).
|
||||||
Str("kernel", q.kernel.KernelPath).
|
|
||||||
Str("user", user).
|
Str("user", user).
|
||||||
Str("cmd", cmd).
|
Str("cmd", cmd)
|
||||||
Logger()
|
|
||||||
|
|
||||||
flog.Debug().Msg("qemu command")
|
q.Log.Debug().Msg("qemu command")
|
||||||
|
|
||||||
client, err := q.ssh(user)
|
client, err := q.ssh(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -400,7 +398,7 @@ func (q System) Command(user, cmd string) (output string, err error) {
|
|||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := scanner.Text()
|
||||||
output += m + "\n"
|
output += m + "\n"
|
||||||
flog.Trace().Str("stdout", m).Msg("")
|
q.Log.Trace().Str("stdout", m).Msg("qemu command")
|
||||||
}
|
}
|
||||||
output = strings.TrimSuffix(output, "\n")
|
output = strings.TrimSuffix(output, "\n")
|
||||||
}()
|
}()
|
||||||
@ -411,7 +409,7 @@ func (q System) Command(user, cmd string) (output string, err error) {
|
|||||||
m := scanner.Text()
|
m := scanner.Text()
|
||||||
output += m + "\n"
|
output += m + "\n"
|
||||||
// Note: it prints stderr as stdout
|
// Note: it prints stderr as stdout
|
||||||
flog.Trace().Str("stdout", m).Msg("")
|
q.Log.Trace().Str("stdout", m).Msg("qemu command")
|
||||||
}
|
}
|
||||||
output = strings.TrimSuffix(output, "\n")
|
output = strings.TrimSuffix(output, "\n")
|
||||||
}()
|
}()
|
||||||
@ -452,7 +450,7 @@ func (q System) scp(user, localPath, remotePath string, recursive bool) (err err
|
|||||||
if recursive {
|
if recursive {
|
||||||
cmd := exec.Command("ssh", "-V")
|
cmd := exec.Command("ssh", "-V")
|
||||||
|
|
||||||
log.Debug().Msgf("%v", cmd)
|
q.Log.Debug().Msgf("%v", cmd)
|
||||||
|
|
||||||
var output []byte
|
var output []byte
|
||||||
output, err = cmd.CombinedOutput()
|
output, err = cmd.CombinedOutput()
|
||||||
@ -461,7 +459,7 @@ func (q System) scp(user, localPath, remotePath string, recursive bool) (err err
|
|||||||
}
|
}
|
||||||
sshVersion := string(output)
|
sshVersion := string(output)
|
||||||
|
|
||||||
log.Debug().Str("ssh version", sshVersion).Msg("")
|
q.Log.Debug().Str("ssh version", sshVersion).Msg("qemu scp")
|
||||||
|
|
||||||
if strings.Contains(sshVersion, "OpenSSH_9") {
|
if strings.Contains(sshVersion, "OpenSSH_9") {
|
||||||
// This release switches scp from using the
|
// This release switches scp from using the
|
||||||
@ -481,7 +479,7 @@ func (q System) scp(user, localPath, remotePath string, recursive bool) (err err
|
|||||||
args = append(args, localPath, user+"@"+addr+":"+remotePath)
|
args = append(args, localPath, user+"@"+addr+":"+remotePath)
|
||||||
|
|
||||||
cmd := exec.Command("scp", args...)
|
cmd := exec.Command("scp", args...)
|
||||||
log.Debug().Msgf("%v", cmd)
|
q.Log.Debug().Msgf("%v", cmd)
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil || string(output) != "" {
|
if err != nil || string(output) != "" {
|
||||||
@ -498,9 +496,9 @@ func (q System) scpWithRetry(user, localPath, remotePath string, recursive bool)
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
q.log.Warn().Err(err).Msg("scp: failed")
|
q.Log.Warn().Err(err).Msg("scp: failed")
|
||||||
time.Sleep(q.SCP.RetryTimeout)
|
time.Sleep(q.SCP.RetryTimeout)
|
||||||
q.log.Warn().Msgf("scp: %d retries left", retries)
|
q.Log.Warn().Msgf("scp: %d retries left", retries)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user