Add support for storing/retrieving transient status
parent
f3ef3f3918
commit
448ec75c8c
|
|
@ -44,6 +44,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/out/register"
|
||||
)
|
||||
|
||||
var deleteAll bool
|
||||
|
|
@ -125,6 +126,7 @@ func runDelete(cmd *cobra.Command, args []string) {
|
|||
if len(args) > 0 {
|
||||
exit.UsageT("Usage: minikube delete")
|
||||
}
|
||||
register.SetEventLogPath(localpath.EventLog(ClusterFlagValue()))
|
||||
|
||||
validProfiles, invalidProfiles, err := config.ListProfiles()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/cruntime"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/exit"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/mustload"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/out/register"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -47,6 +49,7 @@ var pauseCmd = &cobra.Command{
|
|||
|
||||
func runPause(cmd *cobra.Command, args []string) {
|
||||
co := mustload.Running(ClusterFlagValue())
|
||||
register.SetEventLogPath(localpath.EventLog(ClusterFlagValue()))
|
||||
|
||||
for _, n := range co.Config.Nodes {
|
||||
host, err := machine.LoadHost(co.API, driver.MachineName(*co.Config, n))
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ func platform() string {
|
|||
|
||||
// runStart handles the executes the flow of "minikube start"
|
||||
func runStart(cmd *cobra.Command, args []string) {
|
||||
register.SetEventLogPath(localpath.EventLog(ClusterFlagValue()))
|
||||
|
||||
out.SetJSON(viper.GetString(startOutput) == "json")
|
||||
displayVersion(version.GetVersion())
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -24,17 +25,21 @@ import (
|
|||
"strings"
|
||||
"text/template"
|
||||
|
||||
cloudevents "github.com/cloudevents/sdk-go/v2"
|
||||
|
||||
"github.com/docker/machine/libmachine"
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"go.etcd.io/etcd/version"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/bsutil/kverify"
|
||||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/exit"
|
||||
"k8s.io/minikube/pkg/minikube/kubeconfig"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/mustload"
|
||||
"k8s.io/minikube/pkg/minikube/node"
|
||||
|
|
@ -59,14 +64,34 @@ const (
|
|||
Irrelevant = "Irrelevant"
|
||||
)
|
||||
|
||||
type ExperimentalComponent struct {
|
||||
Name string
|
||||
Kind string
|
||||
|
||||
Condition string
|
||||
ConditionDetail []string
|
||||
|
||||
Step string
|
||||
}
|
||||
|
||||
type ExperimentalCluster struct {
|
||||
ExperimentalComponent
|
||||
Components map[string]ExperimentalComponent
|
||||
}
|
||||
|
||||
// Status holds string representations of component states
|
||||
type Status struct {
|
||||
Version string
|
||||
|
||||
Name string
|
||||
Host string
|
||||
Kubelet string
|
||||
APIServer string
|
||||
Kubeconfig string
|
||||
Worker bool
|
||||
|
||||
// Prototyping for the future
|
||||
ExperimentalCluster ExperimentalCluster
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
@ -135,6 +160,8 @@ var statusCmd = &cobra.Command{
|
|||
}
|
||||
}
|
||||
|
||||
addExperimentalFields(statuses[0])
|
||||
|
||||
switch strings.ToLower(output) {
|
||||
case "text":
|
||||
for _, st := range statuses {
|
||||
|
|
@ -154,6 +181,46 @@ var statusCmd = &cobra.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func readEventLog(name string) ([]cloudevents.Event, error) {
|
||||
path := localpath.EventLog(name)
|
||||
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "open")
|
||||
}
|
||||
var events []cloudevents.Event
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
var ev cloudevents.Event
|
||||
if err = json.Unmarshal(scanner.Bytes(), &ev); err != nil {
|
||||
return events, err
|
||||
}
|
||||
events = append(events, ev)
|
||||
}
|
||||
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func addExperimentalFields(st *Status) {
|
||||
st.ExperimentalCluster.Condition = st.APIServer
|
||||
|
||||
evs, err := readEventLog(st.Name)
|
||||
if err != nil {
|
||||
glog.Errorf("unable to read event log: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, ev := range evs {
|
||||
glog.Infof("read event: %+v", ev)
|
||||
/* if ev.Type() == "io.k8s.sigs.minikube.step" {
|
||||
st.ExperimentalCluster.Step = ev.Data.Name
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func exitCode(statuses []*Status) int {
|
||||
c := 0
|
||||
for _, st := range statuses {
|
||||
|
|
@ -176,6 +243,7 @@ func status(api libmachine.API, cc config.ClusterConfig, n config.Node) (*Status
|
|||
name := driver.MachineName(cc, n)
|
||||
|
||||
st := &Status{
|
||||
Version: version.Version,
|
||||
Name: name,
|
||||
Host: Nonexistent,
|
||||
APIServer: Nonexistent,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/mustload"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/out/register"
|
||||
"k8s.io/minikube/pkg/util/retry"
|
||||
)
|
||||
|
||||
|
|
@ -60,6 +61,8 @@ func init() {
|
|||
|
||||
// runStop handles the executes the flow of "minikube stop"
|
||||
func runStop(cmd *cobra.Command, args []string) {
|
||||
register.SetEventLogPath(localpath.EventLog(ClusterFlagValue()))
|
||||
|
||||
// new code
|
||||
var profilesToStop []string
|
||||
if stopAll {
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/cruntime"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/exit"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/mustload"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/out/register"
|
||||
)
|
||||
|
||||
// unpauseCmd represents the docker-pause command
|
||||
|
|
@ -39,6 +41,8 @@ var unpauseCmd = &cobra.Command{
|
|||
Short: "unpause Kubernetes",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cname := ClusterFlagValue()
|
||||
register.SetEventLogPath(localpath.EventLog(cname))
|
||||
|
||||
co := mustload.Running(cname)
|
||||
|
||||
for _, n := range co.Config.Nodes {
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -70,6 +70,7 @@ require (
|
|||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f
|
||||
github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738
|
||||
golang.org/x/build v0.0.0-20190927031335-2835ba2e683f
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
|
|
@ -83,6 +84,7 @@ require (
|
|||
k8s.io/api v0.17.4
|
||||
k8s.io/apimachinery v0.17.4
|
||||
k8s.io/client-go v0.17.4
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/kubectl v0.0.0
|
||||
k8s.io/kubernetes v1.17.3
|
||||
k8s.io/utils v0.0.0-20200229041039-0a110f9eb7ab // indirect
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -244,6 +244,7 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
|||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
|
|
@ -1030,6 +1031,7 @@ github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097 h1:Ucx5I1l1+TWXvqFm
|
|||
github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097/go.mod h1:lFZSWRIpCfE/pt91hHBBpV6+x87YlCjsp+aIR2qCPPU=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ func Profile(name string) string {
|
|||
return filepath.Join(MiniPath(), "profiles", name)
|
||||
}
|
||||
|
||||
// EventLog returns the path to a CloudEvents log
|
||||
func EventLog(name string) string {
|
||||
return filepath.Join(Profile(name), "events.json")
|
||||
}
|
||||
|
||||
// ClientCert returns client certificate path, used by kubeconfig
|
||||
func ClientCert(name string) string {
|
||||
new := filepath.Join(Profile(name), "client.crt")
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ func T(style StyleEnum, format string, a ...V) {
|
|||
register.PrintStep(outStyled)
|
||||
return
|
||||
}
|
||||
register.RecordStep(outStyled)
|
||||
String(outStyled)
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +138,8 @@ func Err(format string, a ...interface{}) {
|
|||
register.PrintError(format)
|
||||
return
|
||||
}
|
||||
register.RecordError(format)
|
||||
|
||||
if errFile == nil {
|
||||
glog.Errorf("[unset errFile]: %s", fmt.Sprintf(format, a...))
|
||||
return
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
cloudevents "github.com/cloudevents/sdk-go/v2"
|
||||
"github.com/golang/glog"
|
||||
|
|
@ -31,11 +32,33 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
OutputFile io.Writer = os.Stdout
|
||||
outputFile io.Writer = os.Stdout
|
||||
GetUUID = randomID
|
||||
|
||||
eventFile *os.File
|
||||
)
|
||||
|
||||
func printAsCloudEvent(log Log, data map[string]string) {
|
||||
func SetOutputFile(w io.Writer) {
|
||||
outputFile = w
|
||||
}
|
||||
|
||||
func SetEventLogPath(path string) {
|
||||
if _, err := os.Stat(filepath.Dir(path)); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
|
||||
glog.Errorf("Error creating profile directory", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
glog.Errorf("unable to write to %s: %v", path, err)
|
||||
return
|
||||
}
|
||||
eventFile = f
|
||||
}
|
||||
|
||||
func cloudEvent(log Log, data map[string]string) cloudevents.Event {
|
||||
event := cloudevents.NewEvent()
|
||||
event.SetSource("https://minikube.sigs.k8s.io/")
|
||||
event.SetType(log.Type())
|
||||
|
|
@ -44,11 +67,57 @@ func printAsCloudEvent(log Log, data map[string]string) {
|
|||
glog.Warningf("error setting data: %v", err)
|
||||
}
|
||||
event.SetID(GetUUID())
|
||||
json, err := event.MarshalJSON()
|
||||
return event
|
||||
}
|
||||
|
||||
func printAsCloudEvent(log Log, data map[string]string) {
|
||||
event := cloudEvent(log, data)
|
||||
|
||||
bs, err := event.MarshalJSON()
|
||||
if err != nil {
|
||||
glog.Warningf("error marashalling event: %v", err)
|
||||
glog.Errorf("error marashalling event: %v", err)
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(OutputFile, string(json))
|
||||
fmt.Fprintln(outputFile, string(bs))
|
||||
}
|
||||
|
||||
func printAndRecordCloudEvent(log Log, data map[string]string) {
|
||||
event := cloudEvent(log, data)
|
||||
|
||||
bs, err := event.MarshalJSON()
|
||||
if err != nil {
|
||||
glog.Errorf("error marashalling event: %v", err)
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(outputFile, string(bs))
|
||||
|
||||
if eventFile != nil {
|
||||
go storeEvent(bs)
|
||||
}
|
||||
}
|
||||
|
||||
func storeEvent(bs []byte) {
|
||||
glog.Errorf("writing to eventfile: %s", string(bs))
|
||||
fmt.Fprintln(eventFile, string(bs))
|
||||
if err := eventFile.Sync(); err != nil {
|
||||
glog.Warningf("even file flush failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func recordCloudEvent(log Log, data map[string]string) {
|
||||
if eventFile == nil {
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
event := cloudEvent(log, data)
|
||||
bs, err := event.MarshalJSON()
|
||||
if err != nil {
|
||||
glog.Errorf("error marashalling event: %v", err)
|
||||
return
|
||||
}
|
||||
storeEvent(bs)
|
||||
}()
|
||||
}
|
||||
|
||||
func randomID() string {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,13 @@ package register
|
|||
// PrintStep prints a Step type in JSON format
|
||||
func PrintStep(message string) {
|
||||
s := NewStep(message)
|
||||
printAsCloudEvent(s, s.data)
|
||||
printAndRecordCloudEvent(s, s.data)
|
||||
}
|
||||
|
||||
// RecordStep records a Step type in JSON format
|
||||
func RecordStep(message string) {
|
||||
s := NewStep(message)
|
||||
recordCloudEvent(s, s.data)
|
||||
}
|
||||
|
||||
// PrintInfo prints an Info type in JSON format
|
||||
|
|
@ -31,7 +37,7 @@ func PrintInfo(message string) {
|
|||
// PrintDownload prints a Download type in JSON format
|
||||
func PrintDownload(artifact string) {
|
||||
s := NewDownload(artifact)
|
||||
printAsCloudEvent(s, s.data)
|
||||
printAndRecordCloudEvent(s, s.data)
|
||||
}
|
||||
|
||||
// PrintDownloadProgress prints a DownloadProgress type in JSON format
|
||||
|
|
@ -43,17 +49,23 @@ func PrintDownloadProgress(artifact, progress string) {
|
|||
// PrintError prints an Error type in JSON format
|
||||
func PrintError(err string) {
|
||||
e := NewError(err)
|
||||
printAsCloudEvent(e, e.data)
|
||||
printAndRecordCloudEvent(e, e.data)
|
||||
}
|
||||
|
||||
// RecordError records a Record type in JSON format
|
||||
func RecordError(err string) {
|
||||
e := NewError(err)
|
||||
recordCloudEvent(e, e.data)
|
||||
}
|
||||
|
||||
// PrintErrorExitCode prints an error in JSON format and includes an exit code
|
||||
func PrintErrorExitCode(err string, exitcode int, additionalArgs ...map[string]string) {
|
||||
e := NewErrorExitCode(err, exitcode, additionalArgs...)
|
||||
printAsCloudEvent(e, e.data)
|
||||
printAndRecordCloudEvent(e, e.data)
|
||||
}
|
||||
|
||||
// PrintWarning prints a Warning type in JSON format
|
||||
func PrintWarning(warning string) {
|
||||
w := NewWarning(warning)
|
||||
printAsCloudEvent(w, w.data)
|
||||
printAndRecordCloudEvent(w, w.data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ func TestPrintStep(t *testing.T) {
|
|||
expected += "\n"
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
OutputFile = buf
|
||||
defer func() { OutputFile = os.Stdout }()
|
||||
SetOutputFile(buf)
|
||||
defer func() { SetOutputFile(os.Stdout) }()
|
||||
|
||||
GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
@ -49,8 +49,8 @@ func TestPrintInfo(t *testing.T) {
|
|||
expected += "\n"
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
OutputFile = buf
|
||||
defer func() { OutputFile = os.Stdout }()
|
||||
SetOutputFile(buf)
|
||||
defer func() { SetOutputFile(os.Stdout) }()
|
||||
|
||||
GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
@ -69,8 +69,8 @@ func TestError(t *testing.T) {
|
|||
expected += "\n"
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
OutputFile = buf
|
||||
defer func() { OutputFile = os.Stdout }()
|
||||
SetOutputFile(buf)
|
||||
defer func() { SetOutputFile(os.Stdout) }()
|
||||
|
||||
GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
@ -89,8 +89,8 @@ func TestErrorExitCode(t *testing.T) {
|
|||
expected += "\n"
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
OutputFile = buf
|
||||
defer func() { OutputFile = os.Stdout }()
|
||||
SetOutputFile(buf)
|
||||
defer func() { SetOutputFile(os.Stdout) }()
|
||||
|
||||
GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
@ -107,8 +107,8 @@ func TestWarning(t *testing.T) {
|
|||
expected += "\n"
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
OutputFile = buf
|
||||
defer func() { OutputFile = os.Stdout }()
|
||||
SetOutputFile(buf)
|
||||
defer func() { SetOutputFile(os.Stdout) }()
|
||||
|
||||
GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
|
|||
|
|
@ -92,3 +92,5 @@ func (r *Register) currentStep() string {
|
|||
func (r *Register) SetStep(s RegStep) {
|
||||
r.current = s
|
||||
}
|
||||
|
||||
// recordStep records the current step
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ func TestSetCurrentStep(t *testing.T) {
|
|||
expected += "\n"
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
OutputFile = buf
|
||||
defer func() { OutputFile = os.Stdout }()
|
||||
SetOutputFile(buf)
|
||||
defer func() { SetOutputFile(os.Stdout) }()
|
||||
|
||||
GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ func TestDisplayJSON(t *testing.T) {
|
|||
for _, tc := range tcs {
|
||||
t.Run(tc.p.ID, func(t *testing.T) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
register.OutputFile = buf
|
||||
defer func() { register.OutputFile = os.Stdout }()
|
||||
register.SetOutputFile(buf)
|
||||
defer func() { register.SetOutputFile(os.Stdout) }()
|
||||
|
||||
register.GetUUID = func() string {
|
||||
return "random-id"
|
||||
|
|
|
|||
Loading…
Reference in New Issue