diff --git a/Makefile b/Makefile index dee62451..fd589490 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,11 @@ MAINMODULE := . COMMONDIR := $(or ${COMMONDIR},../builder) CGO_ENABLED := 1 -in-docker: clean-local-dirs generate-client test all; +in-docker: clean-local-dirs generate-client gofmt test all; include $(COMMONDIR)/Makefile.inc -release:: generate-client test all ; +release:: generate-client gofmt test all ; .PHONY: clean clean:: @@ -93,4 +93,8 @@ qemu-up: DEBUG=1 \ BGP=1" \ -kernel metal-hammer-kernel \ - -initrd metal-hammer-initrd.img.lz4 \ No newline at end of file + -initrd metal-hammer-initrd.img.lz4 + +.PHONY: protoc +protoc: + docker run -it --rm -v $(PWD)/../../..:/work metalstack/builder bash -c "cd github.com/metal-stack/metal-hammer && protoc -I cmd -I../../.. --go_out plugins=grpc:cmd cmd/api/v1/*.proto" diff --git a/cmd/api/v1/wait.pb.go b/cmd/api/v1/wait.pb.go new file mode 100644 index 00000000..89e5c1cd --- /dev/null +++ b/cmd/api/v1/wait.pb.go @@ -0,0 +1,222 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: api/v1/wait.proto + +package v1 + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type WaitRequest struct { + MachineID string `protobuf:"bytes,1,opt,name=machineID,proto3" json:"machineID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WaitRequest) Reset() { *m = WaitRequest{} } +func (m *WaitRequest) String() string { return proto.CompactTextString(m) } +func (*WaitRequest) ProtoMessage() {} +func (*WaitRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c9d6360f924548db, []int{0} +} + +func (m *WaitRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WaitRequest.Unmarshal(m, b) +} +func (m *WaitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WaitRequest.Marshal(b, m, deterministic) +} +func (m *WaitRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WaitRequest.Merge(m, src) +} +func (m *WaitRequest) XXX_Size() int { + return xxx_messageInfo_WaitRequest.Size(m) +} +func (m *WaitRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WaitRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WaitRequest proto.InternalMessageInfo + +func (m *WaitRequest) GetMachineID() string { + if m != nil { + return m.MachineID + } + return "" +} + +type WaitResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WaitResponse) Reset() { *m = WaitResponse{} } +func (m *WaitResponse) String() string { return proto.CompactTextString(m) } +func (*WaitResponse) ProtoMessage() {} +func (*WaitResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c9d6360f924548db, []int{1} +} + +func (m *WaitResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WaitResponse.Unmarshal(m, b) +} +func (m *WaitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WaitResponse.Marshal(b, m, deterministic) +} +func (m *WaitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_WaitResponse.Merge(m, src) +} +func (m *WaitResponse) XXX_Size() int { + return xxx_messageInfo_WaitResponse.Size(m) +} +func (m *WaitResponse) XXX_DiscardUnknown() { + xxx_messageInfo_WaitResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_WaitResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*WaitRequest)(nil), "v1.WaitRequest") + proto.RegisterType((*WaitResponse)(nil), "v1.WaitResponse") +} + +func init() { proto.RegisterFile("api/v1/wait.proto", fileDescriptor_c9d6360f924548db) } + +var fileDescriptor_c9d6360f924548db = []byte{ + // 132 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4c, 0x2c, 0xc8, 0xd4, + 0x2f, 0x33, 0xd4, 0x2f, 0x4f, 0xcc, 0x2c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2a, + 0x33, 0x54, 0xd2, 0xe6, 0xe2, 0x0e, 0x4f, 0xcc, 0x2c, 0x09, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, + 0x11, 0x92, 0xe1, 0xe2, 0xcc, 0x4d, 0x4c, 0xce, 0xc8, 0xcc, 0x4b, 0xf5, 0x74, 0x91, 0x60, 0x54, + 0x60, 0xd4, 0xe0, 0x0c, 0x42, 0x08, 0x28, 0xf1, 0x71, 0xf1, 0x40, 0x14, 0x17, 0x17, 0xe4, 0xe7, + 0x15, 0xa7, 0x1a, 0x19, 0x73, 0xb1, 0x80, 0xf8, 0x42, 0xda, 0x50, 0x9a, 0x5f, 0xaf, 0xcc, 0x50, + 0x0f, 0xc9, 0x38, 0x29, 0x01, 0x84, 0x00, 0x44, 0x8b, 0x01, 0xa3, 0x13, 0x47, 0x14, 0x1b, 0xc4, + 0x29, 0x49, 0x6c, 0x60, 0x67, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x33, 0xf2, 0x18, 0x07, + 0x9b, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// WaitClient is the client API for Wait service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type WaitClient interface { + Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (Wait_WaitClient, error) +} + +type waitClient struct { + cc grpc.ClientConnInterface +} + +func NewWaitClient(cc grpc.ClientConnInterface) WaitClient { + return &waitClient{cc} +} + +func (c *waitClient) Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (Wait_WaitClient, error) { + stream, err := c.cc.NewStream(ctx, &_Wait_serviceDesc.Streams[0], "/v1.Wait/Wait", opts...) + if err != nil { + return nil, err + } + x := &waitWaitClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Wait_WaitClient interface { + Recv() (*WaitResponse, error) + grpc.ClientStream +} + +type waitWaitClient struct { + grpc.ClientStream +} + +func (x *waitWaitClient) Recv() (*WaitResponse, error) { + m := new(WaitResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// WaitServer is the server API for Wait service. +type WaitServer interface { + Wait(*WaitRequest, Wait_WaitServer) error +} + +// UnimplementedWaitServer can be embedded to have forward compatible implementations. +type UnimplementedWaitServer struct { +} + +func (*UnimplementedWaitServer) Wait(req *WaitRequest, srv Wait_WaitServer) error { + return status.Errorf(codes.Unimplemented, "method Wait not implemented") +} + +func RegisterWaitServer(s *grpc.Server, srv WaitServer) { + s.RegisterService(&_Wait_serviceDesc, srv) +} + +func _Wait_Wait_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(WaitRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(WaitServer).Wait(m, &waitWaitServer{stream}) +} + +type Wait_WaitServer interface { + Send(*WaitResponse) error + grpc.ServerStream +} + +type waitWaitServer struct { + grpc.ServerStream +} + +func (x *waitWaitServer) Send(m *WaitResponse) error { + return x.ServerStream.SendMsg(m) +} + +var _Wait_serviceDesc = grpc.ServiceDesc{ + ServiceName: "v1.Wait", + HandlerType: (*WaitServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Wait", + Handler: _Wait_Wait_Handler, + ServerStreams: true, + }, + }, + Metadata: "api/v1/wait.proto", +} diff --git a/cmd/api/v1/wait.proto b/cmd/api/v1/wait.proto new file mode 100644 index 00000000..0bb12908 --- /dev/null +++ b/cmd/api/v1/wait.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package v1; + +option go_package = "api/v1"; + +message WaitRequest { + string machineID = 1; +} + +message WaitResponse {} + +service Wait { + rpc Wait (WaitRequest) returns (stream WaitResponse); +} diff --git a/cmd/bios.go b/cmd/bios.go index 58e2f449..58748713 100644 --- a/cmd/bios.go +++ b/cmd/bios.go @@ -3,7 +3,6 @@ package cmd import ( "github.com/metal-stack/metal-hammer/cmd/event" "github.com/metal-stack/metal-hammer/pkg/kernel" - "github.com/metal-stack/metal-hammer/pkg/sum" "time" log "github.com/inconshreveable/log15" @@ -12,12 +11,11 @@ import ( // ConfigureBIOS ensures that UEFI boot is enabled and CSM-support is disabled. // It then reboots the machine. func (h *Hammer) ConfigureBIOS() error { - s, err := sum.New() - if err != nil { - return err + if h.Spec.DevMode || h.Hal.Board().VM { + return nil } - reboot, err := s.ConfigureBIOS() + reboot, err := h.Hal.ConfigureBIOS() if err != nil { log.Warn("BIOS updates for this machine type are intentionally not supported, skipping ConfigureBIOS", "error", err) return nil @@ -39,16 +37,11 @@ func (h *Hammer) ConfigureBIOS() error { // EnsureBootOrder ensures that the BIOS boot order is properly set, // i.e. first boot from OS image and then PXE boot func (h *Hammer) EnsureBootOrder(bootloaderID string) error { - if h.Spec.DevMode { + if h.Spec.DevMode || h.Hal.Board().VM { return nil } - s, err := sum.New() - if err != nil { - return err - } - - err = s.EnsureBootOrder(bootloaderID) + err := h.Hal.EnsureBootOrder(bootloaderID) if err != nil { return err } diff --git a/cmd/network/lldpclient.go b/cmd/network/lldpclient.go index c9b54cc6..5bcd2fe2 100644 --- a/cmd/network/lldpclient.go +++ b/cmd/network/lldpclient.go @@ -120,11 +120,6 @@ func (l *LLDPClient) requirementsMet() bool { } } } - // OK we found 2 distinct chassis mac's - if len(neighMap) >= l.Host.minimumNeighbors { - return true - } - - // Requirements are not met - return false + // Requirements are met if we found at least 2 distinct chassis mac's + return len(neighMap) >= l.Host.minimumNeighbors } diff --git a/cmd/register/register.go b/cmd/register/register.go index 6eae81a4..50ba29cc 100644 --- a/cmd/register/register.go +++ b/cmd/register/register.go @@ -2,14 +2,6 @@ package register import ( "fmt" - "github.com/jaypipes/ghw" - "github.com/metal-stack/metal-hammer/cmd/network" - "github.com/metal-stack/metal-hammer/cmd/storage" - "github.com/metal-stack/metal-hammer/metal-core/client/machine" - "github.com/metal-stack/metal-hammer/metal-core/models" - "github.com/metal-stack/metal-hammer/pkg/bios" - "github.com/metal-stack/metal-hammer/pkg/ipmi" - "github.com/vishvananda/netlink" "io/ioutil" gonet "net" "strconv" @@ -17,6 +9,15 @@ import ( "syscall" "unsafe" + "github.com/jaypipes/ghw" + "github.com/metal-stack/go-hal" + "github.com/metal-stack/go-hal/pkg/api" + "github.com/metal-stack/metal-hammer/cmd/network" + "github.com/metal-stack/metal-hammer/cmd/storage" + "github.com/metal-stack/metal-hammer/metal-core/client/machine" + "github.com/metal-stack/metal-hammer/metal-core/models" + "github.com/vishvananda/netlink" + log "github.com/inconshreveable/log15" "github.com/pkg/errors" ) @@ -26,6 +27,7 @@ type Register struct { MachineUUID string Client *machine.Client Network *network.Network + Hal hal.InBand } // RegisterMachine register a machine at the metal-api via metal-core @@ -156,13 +158,17 @@ func (r *Register) ReadHardwareDetails() (*models.DomainMetalHammerRegisterMachi hw.Disks = append(hw.Disks, blockDevice) } - ipmiconfig, err := readIPMIDetails(r.Network.Eth0Mac) + ipmiconfig, err := readIPMIDetails(r.Network.Eth0Mac, r.Hal) if err != nil { return nil, err } hw.IPMI = ipmiconfig - b := bios.Bios() + board := r.Hal.Board() + b := board.BIOS + if b == nil { + return nil, errors.New("unable to read bios informations from bmc") + } hw.Bios = &models.ModelsV1MachineBIOS{ Version: &b.Version, Vendor: &b.Vendor, @@ -189,88 +195,76 @@ func createSyslog() error { return ioutil.WriteFile("/var/log/syslog", b[:amt], 0666) } -const defaultIpmiPort = "623" - -// defaultIpmiUser the name of the user created by metal in the ipmi config -const defaultIpmiUser = "metal" - -// defaultIpmiUserID the id of the user created by metal in the ipmi config -const defaultIpmiUserID = "10" - // IPMI configuration and -func readIPMIDetails(eth0Mac string) (*models.ModelsV1MachineIPMI, error) { - config := ipmi.LanConfig{} - var fru models.ModelsV1MachineFru - i := ipmi.New() +func readIPMIDetails(eth0Mac string, hal hal.InBand) (*models.ModelsV1MachineIPMI, error) { var pw string - var user string - var bmcInfo ipmi.BMCInfo - if i.DevicePresent() { + intf := "lanplus" + details := &models.ModelsV1MachineIPMI{ + Interface: &intf, + } + bmcversion := "unknown" + if hal.BMCPresent() { log.Info("ipmi details from bmc") - user = defaultIpmiUser + board := hal.Board() + bmc := board.BMC + if bmc == nil { + return nil, errors.New("unable to read ipmi bmc info configuration") + } + bmcUser := hal.BMCUser().Name // FIXME userid should be verified if available - var err error - pw, err = i.CreateUser(user, defaultIpmiUserID, ipmi.Administrator) + pw, err := hal.BMCCreateUser(hal.BMCUser().ChannelNumber, bmcUser, hal.BMCUser().Uid, api.AdministratorPrivilege, api.PasswordConstraints{ + Length: 10, + NumDigits: 3, + NumSymbols: 0, + NoUpper: false, + AllowRepeat: false, + }) if err != nil { return nil, errors.Wrap(err, "ipmi create user failed") } - config, err = i.GetLanConfig() - if err != nil { - return nil, errors.Wrap(err, "unable to read ipmi lan configuration") - } - log.Debug("register", "ipmi lanconfig", config) - config.IP = config.IP + ":" + defaultIpmiPort - f, err := i.GetFru() - if err != nil { - return nil, errors.Wrap(err, "unable to read ipmi fru configuration") - } - bmcInfo, err = i.GetBMCInfo() - if err != nil { - return nil, errors.Wrap(err, "unable to read ipmi bmc info configuration") - } - fru = models.ModelsV1MachineFru{ - ChassisPartNumber: f.ChassisPartNumber, - ChassisPartSerial: f.ChassisPartSerial, - BoardMfg: f.BoardMfg, - BoardMfgSerial: f.BoardMfgSerial, - BoardPartNumber: f.BoardPartNumber, - ProductManufacturer: f.ProductManufacturer, - ProductPartNumber: f.ProductPartNumber, - ProductSerial: f.ProductSerial, - } - - } else { - log.Info("ipmi details faked") - if len(eth0Mac) == 0 { - eth0Mac = "00:00:00:00:00:00" - } - - macParts := strings.Split(eth0Mac, ":") - lastOctet := macParts[len(macParts)-1] - port, err := strconv.ParseUint(lastOctet, 16, 32) - if err != nil { - return nil, errors.Wrap(err, "unable to parse last octet of eth0 mac to a integer") + bmcversion = bmc.FirmwareRevision + fru := models.ModelsV1MachineFru{ + ChassisPartNumber: bmc.ChassisPartNumber, + ChassisPartSerial: bmc.ChassisPartSerial, + BoardMfg: bmc.BoardMfg, + BoardMfgSerial: bmc.BoardMfgSerial, + BoardPartNumber: bmc.BoardPartNumber, + ProductManufacturer: bmc.ProductManufacturer, + ProductPartNumber: bmc.ProductPartNumber, + ProductSerial: bmc.ProductSerial, } + details.Address = &bmc.IP + details.Mac = &bmc.MAC + details.User = &bmcUser + details.Password = &pw + details.Bmcversion = &bmcversion + details.Fru = &fru + return details, nil + } - const baseIPMIPort = 6230 - // Fixed IP of vagrant environment gateway - config.IP = fmt.Sprintf("192.168.121.1:%d", baseIPMIPort+port) - config.Mac = "00:00:00:00:00:00" - pw = "vagrant" - user = "vagrant" + log.Info("ipmi details faked") + if len(eth0Mac) == 0 { + eth0Mac = "00:00:00:00:00:00" } - intf := "lanplus" - details := &models.ModelsV1MachineIPMI{ - Address: &config.IP, - Mac: &config.Mac, - Password: &pw, - User: &user, - Interface: &intf, - Fru: &fru, - Bmcversion: &bmcInfo.FirmwareRevision, + macParts := strings.Split(eth0Mac, ":") + lastOctet := macParts[len(macParts)-1] + port, err := strconv.ParseUint(lastOctet, 16, 32) + if err != nil { + return nil, errors.Wrap(err, "unable to parse last octet of eth0 mac to a integer") } + const baseIPMIPort = 6230 + // Fixed IP of vagrant environment gateway + bmcIP := fmt.Sprintf("192.168.121.1:%d", baseIPMIPort+port) + bmcMAC := "00:00:00:00:00:00" + pw = "vagrant" + user := "vagrant" + details.Address = &bmcIP + details.Mac = &bmcMAC + details.User = &user + details.Password = &pw + details.Bmcversion = &bmcversion return details, nil } diff --git a/cmd/register/register_test.go b/cmd/register/register_test.go index e29e3817..8f1f3b5a 100644 --- a/cmd/register/register_test.go +++ b/cmd/register/register_test.go @@ -122,7 +122,7 @@ func TestHammer_readIPMIDetails(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := readIPMIDetails("00:00:00:00:00:01") + got, err := readIPMIDetails("00:00:00:00:00:01", nil) if (err != nil) != tt.wantErr { t.Errorf("Hammer.readIPMIDetails() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/cmd/root.go b/cmd/root.go index df6e179c..452d6f10 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,14 +6,15 @@ import ( httptransport "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" log "github.com/inconshreveable/log15" + "github.com/metal-stack/go-hal" "github.com/metal-stack/metal-hammer/cmd/event" "github.com/metal-stack/metal-hammer/cmd/network" "github.com/metal-stack/metal-hammer/cmd/register" "github.com/metal-stack/metal-hammer/cmd/report" "github.com/metal-stack/metal-hammer/cmd/storage" + "github.com/metal-stack/metal-hammer/metal-core/client/certs" "github.com/metal-stack/metal-hammer/metal-core/client/machine" "github.com/metal-stack/metal-hammer/metal-core/models" - "github.com/metal-stack/metal-hammer/pkg/bios" "github.com/metal-stack/metal-hammer/pkg/kernel" "github.com/metal-stack/metal-hammer/pkg/os/command" "github.com/metal-stack/metal-hammer/pkg/password" @@ -22,10 +23,12 @@ import ( // Hammer is the machine which forms a bare metal to a working server type Hammer struct { - Client *machine.Client - Spec *Specification - Disk storage.Disk - LLDPClient *network.LLDPClient + Hal hal.InBand + Client *machine.Client + CertsClient *certs.Client + Spec *Specification + Disk storage.Disk + LLDPClient *network.LLDPClient // IPAddress is the ip of the eth0 interface during installation IPAddress string Started time.Time @@ -35,11 +38,12 @@ type Hammer struct { } // Run orchestrates the whole register/wipe/format/burn and reboot process -func Run(spec *Specification) (*event.EventEmitter, error) { - log.Info("metal-hammer run", "firmware", kernel.Firmware(), "bios", bios.Bios().String()) +func Run(spec *Specification, hal hal.InBand) (*event.EventEmitter, error) { + log.Info("metal-hammer run", "firmware", kernel.Firmware(), "bios", hal.Board().BIOS.String()) transport := httptransport.New(spec.MetalCoreURL, "", nil) client := machine.New(transport, strfmt.Default) + certsClient := certs.New(transport, strfmt.Default) eventEmitter := event.NewEventEmitter(client, spec.MachineUUID) eventEmitter.Emit(event.ProvisioningEventPreparing, "starting metal-hammer") @@ -50,7 +54,9 @@ func Run(spec *Specification) (*event.EventEmitter, error) { } hammer := &Hammer{ + Hal: hal, Client: client, + CertsClient: certsClient, Spec: spec, IPAddress: spec.IP, EventEmitter: eventEmitter, @@ -87,6 +93,7 @@ func Run(spec *Specification) (*event.EventEmitter, error) { MachineUUID: spec.MachineUUID, Client: client, Network: n, + Hal: hal, } hw, err := reg.ReadHardwareDetails() @@ -121,18 +128,16 @@ func Run(spec *Specification) (*event.EventEmitter, error) { return eventEmitter, errors.Wrap(err, "wipe") } - if !spec.DevMode { - err = hammer.ConfigureBIOS() - if err != nil { - log.Error("failed to update BIOS", "error", err) - return eventEmitter, err - } + err = hammer.ConfigureBIOS() + if err != nil { + log.Error("failed to update BIOS", "error", err) + return eventEmitter, err } - eventEmitter.Emit(event.ProvisioningEventWaiting, "waiting for installation") - // Ensure we can run without metal-core, given IMAGE_URL is configured as kernel cmdline if spec.DevMode { + eventEmitter.Emit(event.ProvisioningEventWaiting, "waiting for installation") + cidr := "10.0.1.2" if spec.Cidr != "" { cidr = spec.Cidr @@ -161,7 +166,7 @@ func Run(spec *Specification) (*event.EventEmitter, error) { Hostname: &hostname, SSHPubKeys: sshkeys, Networks: []*models.ModelsV1MachineNetwork{ - &models.ModelsV1MachineNetwork{ + { Ips: []string{cidr}, Asn: &asn, Private: &private, @@ -170,7 +175,7 @@ func Run(spec *Specification) (*event.EventEmitter, error) { Vrf: &vrf, Nat: &nat, }, - &models.ModelsV1MachineNetwork{ + { Ips: []string{"1.2.3.4"}, Asn: &asn, Private: &private2, @@ -208,7 +213,11 @@ func Run(spec *Specification) (*event.EventEmitter, error) { }, } } else { - m, err = hammer.Wait(spec.MachineUUID) + err := hammer.WaitForInstallation(spec.MachineUUID) + if err != nil { + return eventEmitter, errors.Wrap(err, "wait for installation") + } + m, err = hammer.fetchMachine(spec.MachineUUID) if err != nil { return eventEmitter, errors.Wrap(err, "wait for installation") } diff --git a/cmd/spec.go b/cmd/spec.go index ee91527d..d18292d1 100644 --- a/cmd/spec.go +++ b/cmd/spec.go @@ -4,8 +4,6 @@ import ( "strconv" "strings" - "github.com/metal-stack/metal-hammer/pkg/uuid" - "os" "github.com/metal-stack/metal-hammer/pkg/kernel" @@ -44,7 +42,7 @@ type Specification struct { } // NewSpec fills Specification with configuration made by kernel commandline -func NewSpec(ip string) *Specification { +func NewSpec() *Specification { spec := &Specification{} // Grab metal-hammer configuration from kernel commandline envmap, err := kernel.ParseCmdline() @@ -90,8 +88,6 @@ func NewSpec(ip string) *Specification { } } - spec.MachineUUID = uuid.MachineUUID() - spec.IP = ip return spec } @@ -106,5 +102,7 @@ func (s *Specification) Log() { "devmode", s.DevMode, "bgpenabled", s.BGPEnabled, "cidr", s.Cidr, + "machineUUID", s.MachineUUID, + "ip", s.IP, ) } diff --git a/cmd/storage/disk.go b/cmd/storage/disk.go index bc201fd3..a87d449d 100644 --- a/cmd/storage/disk.go +++ b/cmd/storage/disk.go @@ -142,7 +142,7 @@ var ( // String for a Partition func (p *Partition) String() string { - return fmt.Sprintf("%s", p.Device) + return p.Device } // primaryDeviceBySize will configure the disk device where the OS gets installed. @@ -153,6 +153,8 @@ func primaryDeviceBySize(sizeID string, disks []*models.ModelsV1MachineBlockDevi case "nvm-size-x86": // Example how to specify disk partitioning on NVME disks if they need be be used as root disk. return PrimaryDevice{DeviceName: "/dev/nvme0n1", PartitionPrefix: "p"} + case "y1-medium-x86": + return PrimaryDevice{DeviceName: "/dev/nvme0n1", PartitionPrefix: "p"} default: log.Info("getdisk", "sizeID unknown, try to guess disk", sizeID) deviceName := guessDisk(disks) diff --git a/cmd/wait.go b/cmd/wait.go index 6c44d170..50b4cdbd 100644 --- a/cmd/wait.go +++ b/cmd/wait.go @@ -1,61 +1,118 @@ package cmd import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "time" - + "context" + "crypto/tls" + "crypto/x509" + "errors" log "github.com/inconshreveable/log15" - "github.com/metal-stack/metal-hammer/metal-core/models" - "github.com/pkg/errors" + v1 "github.com/metal-stack/metal-hammer/cmd/api/v1" + "github.com/metal-stack/metal-hammer/cmd/event" + "github.com/metal-stack/metal-hammer/metal-core/client/certs" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/keepalive" + "io" + "time" ) // Wait until a machine create request was fired -func (h *Hammer) Wait(uuid string) (*models.ModelsV1MachineResponse, error) { - // We do not use the swagger client because this has no ability to specify a timeout. - e := fmt.Sprintf("http://%v/machine/install/%v", h.Spec.MetalCoreURL, uuid) - log.Info("waiting for install, long polling", "url", e, "uuid", uuid) - - var resp *http.Response - var err error - // Create a http client with a specific timeout to prevent a infinite wait - // which could lead to a situation where e.g network outages would never be - // detected and we will never recover from this situation. - client := http.Client{ - Timeout: time.Duration(5 * time.Minute), - } - for { - resp, err = client.Get(e) - if err != nil { - log.Error("wait for install failed, retrying in 30sec...", "error", err) - time.Sleep(30 * time.Second) - continue - } - if resp.StatusCode == http.StatusOK { - break - } - if resp.StatusCode == http.StatusGatewayTimeout || resp.StatusCode == http.StatusNotModified { - log.Info("wait for install timeout retrying...", "statuscode", resp.StatusCode) - continue - } - log.Warn("wait for install timeout with unexpected returncode retrying in 5sec", "statuscode", resp.StatusCode) - time.Sleep(5 * time.Second) +func (h *Hammer) WaitForInstallation(uuid string) error { + params := certs.NewGrpcClientCertParams() + resp, err := h.CertsClient.GrpcClientCert(params) + if err != nil { + return err } - machineJSON, err := ioutil.ReadAll(resp.Body) + clientCert, err := tls.X509KeyPair([]byte(resp.Payload.Cert), []byte(resp.Payload.Key)) + if err != nil { + return err + } + caCertPool := x509.NewCertPool() + ok := caCertPool.AppendCertsFromPEM([]byte(resp.Payload.CaCert)) + if !ok { + return errors.New("bad certificate") + } + tlsConfig := &tls.Config{ + RootCAs: caCertPool, + Certificates: []tls.Certificate{clientCert}, + } + c, err := NewClient(resp.Payload.Address, tlsConfig, h.EventEmitter) if err != nil { - return nil, errors.Wrap(err, "wait for install reading response failed") + return err + } + defer c.Close() + c.WaitForInstallation(uuid) + return nil +} + +type Client struct { + v1.WaitClient + conn *grpc.ClientConn + emitter *event.EventEmitter +} + +func NewClient(addr string, tlsConfig *tls.Config, emitter *event.EventEmitter) (*Client, error) { + kacp := keepalive.ClientParameters{ + Time: 10 * time.Second, // send pings every 10 seconds if there is no activity + Timeout: time.Second, // wait 1 second for ping ack before considering the connection dead + PermitWithoutStream: true, // send pings even without active streams } - log.Info("wait finished", "statuscode", resp.StatusCode, "response", string(machineJSON)) - var machine models.ModelsV1MachineResponse - err = json.Unmarshal(machineJSON, &machine) + opts := []grpc.DialOption{ + grpc.WithKeepaliveParams(kacp), + grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), + grpc.WithBlock(), + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + conn, err := grpc.DialContext(ctx, addr, opts...) if err != nil { - return nil, errors.Wrap(err, "wait for install could not unmarshal response") + return nil, err + } + + c := &Client{ + WaitClient: v1.NewWaitClient(conn), + conn: conn, + emitter: emitter, + } + + return c, nil +} + +func (c *Client) Close() error { + return c.conn.Close() +} + +func (c *Client) WaitForInstallation(machineID string) { + req := &v1.WaitRequest{ + MachineID: machineID, } - log.Info("stopped waiting got", "machine", machine) - return &machine, nil + c.emitter.Emit(event.ProvisioningEventWaiting, "waiting for installation") + + for { + stream, err := c.Wait(context.Background(), req) + if err != nil { + log.Error("failed waiting for installation, retry in 2sec", "error", err) + time.Sleep(2 * time.Second) + continue + } + + for { + _, err := stream.Recv() + if err == io.EOF { + log.Info("machine has been requested for installation", "machineID", machineID) + return + } + + if err != nil { + log.Error("failed waiting for installation, retry in 2sec", "error", err) + time.Sleep(2 * time.Second) + break + } + + log.Info("wait for installation...", "machineID", machineID) + } + } } diff --git a/go.mod b/go.mod index 4b3e8e5d..cd3fee04 100644 --- a/go.mod +++ b/go.mod @@ -1,46 +1,43 @@ module github.com/metal-stack/metal-hammer require ( - github.com/avast/retry-go v2.4.3+incompatible - github.com/beevik/ntp v0.2.0 + github.com/beevik/ntp v0.3.0 github.com/dsnet/compress v0.0.1 // indirect - github.com/fatih/color v1.7.0 // indirect - github.com/frankban/quicktest v1.5.0 // indirect - github.com/go-openapi/analysis v0.19.7 // indirect - github.com/go-openapi/errors v0.19.3 - github.com/go-openapi/runtime v0.19.9 - github.com/go-openapi/spec v0.19.5 // indirect - github.com/go-openapi/strfmt v0.19.4 - github.com/go-openapi/swag v0.19.6 - github.com/go-openapi/validate v0.19.5 - github.com/golang/snappy v0.0.1 // indirect + github.com/fatih/color v1.9.0 // indirect + github.com/frankban/quicktest v1.10.0 // indirect + github.com/go-openapi/analysis v0.19.10 // indirect + github.com/go-openapi/errors v0.19.4 + github.com/go-openapi/runtime v0.19.15 + github.com/go-openapi/strfmt v0.19.5 + github.com/go-openapi/swag v0.19.9 + github.com/go-openapi/validate v0.19.8 + github.com/golang/protobuf v1.4.0-rc.4 github.com/google/gopacket v1.1.17 github.com/google/uuid v1.1.1 - github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec - github.com/jaypipes/ghw v0.5.0 - github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.11 // indirect - github.com/mattn/go-runewidth v0.0.7 // indirect + github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 + github.com/jaypipes/ghw v0.6.0 + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5 github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065 - github.com/metal-stack/v v1.0.1 + github.com/metal-stack/go-hal v0.1.10 + github.com/metal-stack/v v1.0.2 // archiver must stay in version v2.1.0, see replace below github.com/mholt/archiver v3.1.1+incompatible - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/nwaples/rardecode v1.0.0 // indirect - github.com/pierrec/lz4 v2.4.0+incompatible - github.com/pkg/errors v0.8.1 - github.com/stretchr/testify v1.4.0 + github.com/nwaples/rardecode v1.1.0 // indirect + github.com/pierrec/lz4 v2.5.2+incompatible + github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.5.1 github.com/u-root/u-root v6.0.0+incompatible github.com/vishvananda/netlink v1.0.0 github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect - go.mongodb.org/mongo-driver v1.2.0 // indirect - golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 - golang.org/x/sys v0.0.0-20191218084908-4a24b4065292 + golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd + google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c // indirect + google.golang.org/grpc v1.28.1 + google.golang.org/protobuf v1.20.1 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 - gopkg.in/yaml.v2 v2.2.7 + gopkg.in/yaml.v2 v2.2.8 ) replace github.com/mholt/archiver => github.com/mholt/archiver v2.1.0+incompatible diff --git a/go.sum b/go.sum index 74fbe004..c317cd2c 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,26 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/avast/retry-go v2.4.3+incompatible h1:c/FTk2POrEQyZfaHBMkMrXdu3/6IESJUHwu8r3k1JEU= -github.com/avast/retry-go v2.4.3+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw= -github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/avast/retry-go v2.6.0+incompatible h1:FelcMrm7Bxacr1/RM8+/eqkDkmVN7tjlsy51dOzB3LI= +github.com/avast/retry-go v2.6.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= +github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw= +github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -20,27 +29,34 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/frankban/quicktest v1.5.0 h1:Tb4jWdSpdjKzTUicPnY61PZxKbDoGa7ABbrReT3gQVY= -github.com/frankban/quicktest v1.5.0/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= -github.com/go-openapi/analysis v0.19.7 h1:OcMMVVJBRiSsAkXQwSVL4sRrVaqeqPnOcy1Kw0JI47w= -github.com/go-openapi/analysis v0.19.7/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.10 h1:5BHISBAXOc/aJK25irLZnx2D3s6WyYaY9D4gmuz9fdE= +github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3 h1:7MGZI1ibQDLasvAz8HuhvYk9eNJbJkCOXWsSjjMS+Zc= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.4 h1:fSGwO1tSYHFu70NKaWJt5Qh0qoBRtCm/mXS1yhf+0W0= +github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= @@ -61,14 +77,14 @@ github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCs github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= -github.com/go-openapi/runtime v0.19.9 h1:Ay3ckvUJy9iTA4F6EWjx4c2/o3dfHiYdwJbOqIvGLx4= -github.com/go-openapi/runtime v0.19.9/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.15 h1:2GIefxs9Rx1vCDNghRtypRq+ig8KSLrjHbAYI/gCLCM= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw= -github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.6 h1:rMMMj8cV38KVXK7SFc+I2MWClbEfbK705+j+dyqun5g= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= @@ -76,42 +92,90 @@ github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6 github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.4 h1:eRvaqAhpL0IL6Trh5fDsGnGhiXndzHFuA05w6sXH6/g= github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.6 h1:JSUbVWlaTLMhXeOMyArSUNCdroxZu2j1TcrsOV8Mj7Q= -github.com/go-openapi/swag v0.19.6/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s= +github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= -github.com/go-openapi/validate v0.19.5 h1:QhCBKRYqZR+SKo4gl1lPhPahope8/RLt6EVgY8X80w0= -github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys= +github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4 h1:+EOh4OY6tjM6ZueeUKinl1f0U2820HzQOuf1iqMnsks= +github.com/golang/protobuf v1.4.0-rc.4/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec h1:CGkYB1Q7DSsH/ku+to+foV4agt2F2miquaLUgF6L178= -github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= +github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 h1:KUDFlmBg2buRWNzIcwLlKvfcnujcHQRQ1As1LoaCLAM= +github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jaypipes/ghw v0.5.0 h1:Qocnm0cFGVSLkamVQMhOuiUKTdcsG74qvVw8xFaOuzc= -github.com/jaypipes/ghw v0.5.0/go.mod h1:pFqHjEEJFQHrHpZifJ+BBMG+CfGQK7jLLkAqZrRQ7gQ= +github.com/jaypipes/ghw v0.6.0 h1:YGPxlDG9nmiZLWosU1fq+PaBMxNKE07PFg8Y6e6VPto= +github.com/jaypipes/ghw v0.6.0/go.mod h1:QOXppNRCLGYR1H+hu09FxZPqjNt09bqUZUnOL3Rcero= github.com/jaypipes/pcidb v0.5.0 h1:4W5gZ+G7QxydevI8/MmmKdnIPJpURqJ2JNXTzfLxF5c= github.com/jaypipes/pcidb v0.5.0/go.mod h1:L2RGk04sfRhp5wvHO0gfRAMoLY/F3PKv/nwJeVoho0o= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -122,13 +186,21 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 h1:lez6TS6aAau+8wXUP3G9I3TGlmPFEq2CTxBaRqY6AGE= github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y= github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5 h1:i4JJtLb5iDVsncU7splD9ZCQXvxN13tGDUWihfKOq18= @@ -136,28 +208,44 @@ github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5/go.mod h1:IZAsRpRUv/ github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065 h1:aFkJ6lx4FPip+S+Uw4aTegFMct9shDvP+79PsSxpm3w= github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= -github.com/metal-stack/v v1.0.1 h1:N0dy3N8drkarX2b7RiwzzjEBoO1t7dGY03o+m4cEv1U= -github.com/metal-stack/v v1.0.1/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= +github.com/metal-stack/go-hal v0.1.10 h1:35/QgiA9zZbkcLRgBQjgZj8SY2QJ2Y75t1iw/joJUTg= +github.com/metal-stack/go-hal v0.1.10/go.mod h1:WF7Gwkrx/VjwDyhFWis29jE3o9K8k5wxIMI7cSdzERY= +github.com/metal-stack/v v1.0.2 h1:IGtLAGtazQd8r0i/5+YNjBJUEIZYrbVxynY9EXrlTV4= +github.com/metal-stack/v v1.0.2/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= github.com/mholt/archiver v2.1.0+incompatible h1:1ivm7KAHPtPere1YDOdrY6xGdbMNGRWThZbYh5lWZT0= github.com/mholt/archiver v2.1.0+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= +github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs= -github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= +github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pierrec/lz4 v2.4.0+incompatible h1:06usnXXDNcPvCHDkmPpkidf4jTc52UKld7UPfqKatY4= -github.com/pierrec/lz4 v2.4.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sethvargo/go-password v0.1.2 h1:fhBF4thiPVKEZ7R6+CX46GWJiPyCyXshbeqZ7lqEeYo= +github.com/sethvargo/go-password v0.1.2/go.mod h1:qKHfdSjT26DpHQWHWWR5+X4BI45jT31dg6j4RI2TEb0= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stmcginnis/gofish v0.4.0 h1:Tr3wPS4jDXUVMxTIrmPDCyE++CJx8AG/5vFmn5MW8qs= +github.com/stmcginnis/gofish v0.4.0/go.mod h1:t0RUeoOLznx9vExQOeLZUrjU0u3yy0wL4iVMQviUl+k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -165,6 +253,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/u-root/u-root v6.0.0+incompatible h1:YqPGmRoRyYmeg17KIWFRSyVq6LX5T6GSzawyA6wG6EE= @@ -176,16 +266,30 @@ github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCO github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vmware/goipmi v0.0.0-20181114221114-2333cd82d702 h1:yx587LNBbOpIxzCBHBiI94Wx8ryIAFlu1w0lDwm64cA= +github.com/vmware/goipmi v0.0.0-20181114221114-2333cd82d702/go.mod h1:YiWonbS/PuCtti3wt9jl+FvNEJ7c0nvmjGoEYxdjyk0= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= 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= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.2.0 h1:6fhXjXSzzXRQdqtFKOI1CDw6Gw5x6VflovRpfbrlVi0= -go.mongodb.org/mongo-driver v1.2.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.0 h1:ew6uUIeJOo+qdUUv7LxFCUhtWmVv7ZV/Xuy4FAUsw2E= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -193,37 +297,83 @@ golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191218084908-4a24b4065292 h1:Y8q0zsdcgAd+JU8VUA8p8Qv2YhuY9zevDG2ORt5qBUI= -golang.org/x/sys v0.0.0-20191218084908-4a24b4065292/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.20.1 h1:ESRXHgpUBG5D2I5mmsQIyYxB/tQIZfSZ8wLyFDf/N/U= +google.golang.org/protobuf v1.20.1/go.mod h1:KqelGeouBkcbcuB3HCk4/YH2tmNLk6YSWA5LIWeI/lY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= diff --git a/main.go b/main.go index 5910c98c..7deed2a7 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,12 @@ package main import ( "fmt" - "github.com/metal-stack/v" - "os" "time" log "github.com/inconshreveable/log15" + "github.com/metal-stack/go-hal/detect" "github.com/metal-stack/metal-hammer/cmd" "github.com/metal-stack/metal-hammer/cmd/event" "github.com/metal-stack/metal-hammer/cmd/network" @@ -21,12 +20,29 @@ func main() { // Reboot if metal-hammer crashes after 60sec. go kernel.Watchdog() + if len(os.Args) > 1 { + log.Error("cmd args are not supported") + os.Exit(1) + } + err := updateResolvConf() if err != nil { log.Error("error updating resolv.conf", "error", err) os.Exit(1) } + hal, err := detect.ConnectInBand() + if err != nil { + log.Error("unable to detect hardware", "error", err) + os.Exit(1) + } + + uuid, err := hal.UUID() + if err != nil { + log.Error("unable to get uuid hardware", "error", err) + os.Exit(1) + } + ip := network.InternalIP() err = cmd.StartSSHD(ip) if err != nil { @@ -34,14 +50,12 @@ func main() { os.Exit(1) } - if len(os.Args) > 1 { - log.Error("cmd args are not supported") - os.Exit(1) - } + log.Info("metal-hammer", "version", v.V, "hal", hal.Describe()) - log.Info("metal-hammer", "version", v.V) + spec := cmd.NewSpec() + spec.MachineUUID = uuid.String() + spec.IP = ip - spec := cmd.NewSpec(ip) spec.Log() var level log.Lvl @@ -55,7 +69,7 @@ func main() { h = log.LvlFilterHandler(level, h) log.Root().SetHandler(h) - emitter, err := cmd.Run(spec) + emitter, err := cmd.Run(spec, hal) if err != nil { wait := 5 * time.Second st := errors.WithStack(err) @@ -86,10 +100,5 @@ func updateResolvConf() error { return err } - err = os.Symlink(target, symlink) - if err != nil { - return err - } - - return nil + return os.Symlink(target, symlink) } diff --git a/metal-core.json b/metal-core.json index d647ac8b..c6b2328f 100644 --- a/metal-core.json +++ b/metal-core.json @@ -19,6 +19,22 @@ "initrd" ] }, + "domain.GrpcResponse": { + "properties": { + "address": { + "type": "string" + }, + "ca_cert": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "key": { + "type": "string" + } + } + }, "domain.MetalHammerAbortReinstallRequest": { "properties": { "primary_disk_wiped": { @@ -177,12 +193,18 @@ "changed": { "type": "string" }, + "classification": { + "type": "string" + }, "created": { "type": "string" }, "description": { "type": "string" }, + "expirationDate": { + "type": "string" + }, "features": { "items": { "type": "string" @@ -197,13 +219,21 @@ }, "url": { "type": "string" + }, + "usedby": { + "items": { + "type": "string" + }, + "type": "array" } }, "required": [ "changed", "created", + "expirationDate", "features", - "id" + "id", + "usedby" ] }, "models.V1MachineAllocation": { @@ -780,29 +810,12 @@ "version": "1.0.0" }, "paths": { - "/machine/abort-reinstall/{id}": { - "post": { + "/certs/grpc-client-cert": { + "get": { "consumes": [ "application/json" ], - "operationId": "AbortReinstall", - "parameters": [ - { - "description": "identifier of the machine", - "in": "path", - "name": "id", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/domain.MetalHammerAbortReinstallRequest" - } - } - ], + "operationId": "GrpcClientCert", "produces": [ "application/json" ], @@ -810,28 +823,28 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.V1BootInfo" + "$ref": "#/definitions/domain.GrpcResponse" } }, - "400": { - "description": "Bad request" - }, "500": { "description": "Error" + }, + "default": { + "description": "Error" } }, - "summary": "abort reinstall machine", + "summary": "retrieves the client certificate of the gRPC server", "tags": [ - "machine" + "certs" ] } }, - "/machine/install/{id}": { - "get": { + "/machine/abort-reinstall/{id}": { + "post": { "consumes": [ "application/json" ], - "operationId": "Install", + "operationId": "AbortReinstall", "parameters": [ { "description": "identifier of the machine", @@ -839,6 +852,14 @@ "name": "id", "required": true, "type": "string" + }, + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/domain.MetalHammerAbortReinstallRequest" + } } ], "produces": [ @@ -848,23 +869,17 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.V1MachineResponse" + "$ref": "#/definitions/models.V1BootInfo" } }, - "304": { - "description": "No allocation" - }, - "404": { - "description": "Not Found" - }, - "417": { - "description": "Incomplete machine" + "400": { + "description": "Bad request" }, "500": { "description": "Error" } }, - "summary": "install machine", + "summary": "abort reinstall machine", "tags": [ "machine" ] diff --git a/pkg/bios/bios.go b/pkg/bios/bios.go deleted file mode 100644 index 9a827cb4..00000000 --- a/pkg/bios/bios.go +++ /dev/null @@ -1,47 +0,0 @@ -package bios - -import ( - "io/ioutil" - "os" - "strings" - - log "github.com/inconshreveable/log15" -) - -const ( - biosVersion = "/sys/class/dmi/id/bios_version" - biosVendor = "/sys/class/dmi/id/bios_vendor" - biosDate = "/sys/class/dmi/id/bios_date" -) - -// BIOS information of this machine -type BIOS struct { - Version string - Vendor string - Date string -} - -// Bios read bios informations -func Bios() *BIOS { - return &BIOS{ - Version: read(biosVersion), - Vendor: read(biosVendor), - Date: read(biosDate), - } -} - -func (b *BIOS) String() string { - return "version:" + b.Version + " vendor:" + b.Vendor + " date:" + b.Date -} - -func read(file string) string { - if _, err := os.Stat(file); !os.IsNotExist(err) { - content, err := ioutil.ReadFile(file) - if err != nil { - log.Error("error reading", "file", file, "error", err) - return "" - } - return strings.TrimSpace(string(content)) - } - return "" -} diff --git a/pkg/bios/bios_test.go b/pkg/bios/bios_test.go deleted file mode 100644 index 3a18194e..00000000 --- a/pkg/bios/bios_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package bios - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestBios(t *testing.T) { - - bios := Bios() - assert.NotNil(t, bios) - assert.NotEqual(t, bios.Version, "") - assert.NotEqual(t, bios.Vendor, "") - assert.NotEqual(t, bios.Date, "") - assert.NotEqual(t, bios.String(), "") - assert.True(t, strings.HasPrefix(bios.String(), "version")) -} diff --git a/pkg/ipmi/ipmi.go b/pkg/ipmi/ipmi.go deleted file mode 100644 index d399941e..00000000 --- a/pkg/ipmi/ipmi.go +++ /dev/null @@ -1,313 +0,0 @@ -package ipmi - -// IPMI Wiki -// https://www.thomas-krenn.com/de/wiki/IPMI_Konfiguration_unter_Linux_mittels_ipmitool -// -// Oder: -// https://wiki.hetzner.de/index.php/IPMI - -import ( - "bufio" - "fmt" - "os/exec" - "path/filepath" - "reflect" - "strings" - "time" - - "github.com/avast/retry-go" - log "github.com/inconshreveable/log15" - "github.com/metal-stack/metal-hammer/pkg/os/command" - "github.com/metal-stack/metal-hammer/pkg/password" - "github.com/pkg/errors" -) - -// Privilege of a ipmitool user -type Privilege int - -const ( - // Command is the ipmi cli to execute - Command = command.IPMITool - // Callback ipmi privilege - Callback = Privilege(1) - // User ipmi privilege - User = Privilege(2) - // Operator ipmi privilege - Operator = Privilege(3) - // Administrator ipmi privilege - Administrator = Privilege(4) - // OEM ipmi privilege - OEM = Privilege(5) - // NoAccess ipmi privilege - NoAccess = Privilege(15) -) - -// Ipmi defines methods to interact with ipmi -type Ipmi interface { - DevicePresent() bool - Run(arg ...string) (string, error) - CreateUser(username, uid string, privilege Privilege) (string, error) - GetLanConfig() (LanConfig, error) - EnableUEFI(bootdev Bootdev, persistent bool) error - GetFru() (Fru, error) - GetSession() (Session, error) - GetBMCInfo() (BMCInfo, error) -} - -// Ipmitool is used to query and modify the IPMI based BMC from the host os. -type Ipmitool struct { - Command string -} - -// LanConfig contains the config of ipmi. -// tag must contain first column name of ipmitool lan print command output -// to get the second column value be parsed into the field. -type LanConfig struct { - IP string `ipmitool:"IP Address"` - Mac string `ipmitool:"MAC Address"` -} - -func (l *LanConfig) String() string { - return fmt.Sprintf("ip: %s mac:%s", l.IP, l.Mac) -} - -// Session information of the current ipmi session -type Session struct { - UserID string `ipmitool:"user id"` - Privilege string `ipmitool:"privilege level"` -} - -// Fru contains Field Replacable Unit information, retrieved with ipmitool fru -type Fru struct { - // FRU Device Description : Builtin FRU Device (ID 0) - // Chassis Type : Other - // Chassis Part Number : CSE-217BHQ+-R2K22BP2 - // Chassis Serial : C217BAH31AG0535 - // Board Mfg Date : Mon Jan 1 01:00:00 1996 - // Board Mfg : Supermicro - // Board Product : NONE - // Board Serial : HM187S003231 - // Board Part Number : X11DPT-B - // Product Manufacturer : Supermicro - // Product Name : NONE - // Product Part Number : SYS-2029BT-HNTR - // Product Version : NONE - // Product Serial : A328789X9108135 - - ChassisPartNumber string `ipmitool:"Chassis Part Number"` - ChassisPartSerial string `ipmitool:"Chassis Serial"` - BoardMfg string `ipmitool:"Board Mfg"` - BoardMfgSerial string `ipmitool:"Board Mfg Serial"` - BoardPartNumber string `ipmitool:"Board Part Number"` - ProductManufacturer string `ipmitool:"Product Manufacturer"` - ProductPartNumber string `ipmitool:"Product Part Number"` - ProductSerial string `ipmitool:"Product Serial"` -} - -// BMCInfo contains the parsed output of ipmitool bmc info -type BMCInfo struct { - // # ipmitool bmc info - // Device ID : 32 - // Device Revision : 1 - // Firmware Revision : 1.64 - // IPMI Version : 2.0 - // Manufacturer ID : 10876 - // Manufacturer Name : Supermicro - // Product ID : 2402 (0x0962) - // Product Name : Unknown (0x962) - // Device Available : yes - // Provides Device SDRs : no - // Additional Device Support : - FirmwareRevision string `ipmitool:"Firmware Revision"` -} - -// Bootdev specifies from which device to boot -type Bootdev string - -const ( - // PXE boot server via PXE - PXE = Bootdev("pxe") - // Disk boot server from hard disk - Disk = Bootdev("disk") -) - -// New create a new Ipmitool with the default command -func New() Ipmi { - return &Ipmitool{Command: Command} -} - -// DevicePresent returns true if the ipmi device is present, which is required to talk to the BMC. -func (i *Ipmitool) DevicePresent() bool { - const ipmiDevicePrefix = "/dev/ipmi*" - matches, err := filepath.Glob(ipmiDevicePrefix) - if err != nil { - return false - } - return len(matches) > 0 -} - -// Run execute ipmitool -func (i *Ipmitool) Run(args ...string) (string, error) { - path, err := exec.LookPath(i.Command) - if err != nil { - return "", errors.Wrapf(err, "unable to locate program:%s in path", i.Command) - } - cmd := exec.Command(path, args...) - output, err := cmd.Output() - - log.Debug("run ipmitool", "args", args, "output", string(output), "error", err) - return string(output), err -} - -// GetFru returns the Field Replacable Unit information -func (i *Ipmitool) GetFru() (Fru, error) { - config := &Fru{} - cmdOutput, err := i.Run("fru") - if err != nil { - return *config, errors.Wrapf(err, "unable to execute ipmitool 'fru':%v", cmdOutput) - } - fruMap := output2Map(cmdOutput) - from(config, fruMap) - return *config, nil -} - -// GetBMCInfo returns the bmc info -func (i *Ipmitool) GetBMCInfo() (BMCInfo, error) { - bmc := &BMCInfo{} - cmdOutput, err := i.Run("bmc", "info") - if err != nil { - return *bmc, errors.Wrapf(err, "unable to execute ipmitool 'bmc info':%v", cmdOutput) - } - bmcMap := output2Map(cmdOutput) - from(bmc, bmcMap) - return *bmc, nil -} - -// GetLanConfig returns the LanConfig -func (i *Ipmitool) GetLanConfig() (LanConfig, error) { - config := &LanConfig{} - cmdOutput, err := i.Run("lan", "print") - if err != nil { - return *config, errors.Wrapf(err, "unable to execute ipmitool 'lan print':%v", cmdOutput) - } - lanConfigMap := output2Map(cmdOutput) - from(config, lanConfigMap) - return *config, nil -} - -// GetSession returns the Session info -func (i *Ipmitool) GetSession() (Session, error) { - session := &Session{} - cmdOutput, err := i.Run("session", "info", "all") - if err != nil { - return *session, errors.Wrapf(err, "unable to execute ipmitool 'session info all':%v", cmdOutput) - } - sessionMap := output2Map(cmdOutput) - from(session, sessionMap) - return *session, nil -} - -// CreateUser create a ipmi user with password and privilege level -func (i *Ipmitool) CreateUser(username, uid string, privilege Privilege) (string, error) { - out, err := i.Run("user", "set", "name", uid, username) - if err != nil { - return "", errors.Wrapf(err, "unable to create user %s: %v", username, out) - } - // This happens from time to time for unknown reason - // retry password creation max 30 times with 1 second delay - pw := "" - err = retry.Do( - func() error { - pw = password.Generate(10) - out, err = i.Run("user", "set", "password", uid, pw) - if err != nil { - log.Error("ipmi password creation failed", "user", username, "output", out) - } - return err - }, - retry.OnRetry(func(n uint, err error) { - log.Debug("retry ipmi password creation", "user", username, "id", uid, "retry", n) - }), - retry.Delay(1*time.Second), - retry.Attempts(30), - ) - if err != nil { - return pw, errors.Wrapf(err, "unable to set password for user %s: %v", username, out) - } - - channelnumber := "1" - out, err = i.Run("channel", "setaccess", channelnumber, uid, "link=on", "ipmi=on", "callin=on", fmt.Sprintf("privilege=%d", int(privilege))) - if err != nil { - return pw, errors.Wrapf(err, "unable to set privilege for user %s: %v", username, out) - } - out, err = i.Run("user", "enable", uid) - if err != nil { - return pw, errors.Wrapf(err, "unable to enable user %s: %v", username, out) - } - out, err = i.Run("sol", "payload", "enable", channelnumber, uid) - if err != nil { - return pw, errors.Wrapf(err, "unable to enable user %s for sol access: %v", username, out) - } - - return pw, nil -} - -// EnableUEFI set the firmware to boot with uefi for given bootdev, -// bootdev can be one of pxe|disk -// if persistent is set to true this will last for every subsequent boot, not only the next. -func (i *Ipmitool) EnableUEFI(bootdev Bootdev, persistent bool) error { - // for reference: https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf (page 422) - var uefiQualifier, devQualifier string - if persistent { - uefiQualifier = "0xe0" - } else { - uefiQualifier = "0xa0" - } - switch bootdev { - case PXE: - devQualifier = "0x04" - default: - devQualifier = "0x24" // conforms to open source SMCIPMITool, IPMI 2.0 conform byte would be 0x08 - } - out, err := i.Run("raw", "0x00", "0x08", "0x05", uefiQualifier, devQualifier, "0x00", "0x00", "0x00") - if err != nil { - return errors.Wrapf(err, "unable to enable uefi on:%s persistent:%t out:%v", bootdev, persistent, out) - } - return nil -} - -func output2Map(cmdOutput string) map[string]string { - result := make(map[string]string) - scanner := bufio.NewScanner(strings.NewReader(cmdOutput)) - for scanner.Scan() { - line := scanner.Text() - parts := strings.SplitN(line, ":", 2) - if len(parts) < 2 { - continue - } - key := strings.TrimSpace(parts[0]) - if key == "" { - continue - } - value := strings.TrimSpace(strings.Join(parts[1:], "")) - result[key] = value - } - for k, v := range result { - log.Debug("output", "key", k, "value", v) - } - return result -} - -// from uses reflection to fill a struct based on the tags on it. -func from(target interface{}, input map[string]string) { - log.Debug("from", "target", target, "input", input) - val := reflect.ValueOf(target).Elem() - for i := 0; i < val.NumField(); i++ { - valueField := val.Field(i) - typeField := val.Type().Field(i) - tag := typeField.Tag - - ipmitoolKey := tag.Get("ipmitool") - valueField.SetString(input[ipmitoolKey]) - } -} diff --git a/pkg/ipmi/ipmi_test.go b/pkg/ipmi/ipmi_test.go deleted file mode 100644 index 3d148700..00000000 --- a/pkg/ipmi/ipmi_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package ipmi - -import ( - "reflect" - "testing" -) - -// Output of root@ipmitest:~# ipmitool lan print -const lanPrint = ` -Set in Progress : Set Complete -Auth Type Support : NONE MD2 MD5 PASSWORD -Auth Type Enable : Callback : MD2 MD5 PASSWORD - : User : MD2 MD5 PASSWORD - : Operator : MD2 MD5 PASSWORD - : Admin : MD2 MD5 PASSWORD - : OEM : MD2 MD5 PASSWORD -IP Address Source : Static Address -IP Address : 10.248.36.246 -Subnet Mask : 255.255.252.0 -MAC Address : 0c:c4:7a:ed:3e:27 -SNMP Community String : public -IP Header : TTL=0x00 Flags=0x00 Precedence=0x00 TOS=0x00 -BMC ARP Control : ARP Responses Enabled, Gratuitous ARP Disabled -Default Gateway IP : 10.248.36.1 -Default Gateway MAC : 30:b6:4f:c3:a0:c1 -Backup Gateway IP : 0.0.0.0 -Backup Gateway MAC : 00:00:00:00:00:00 -802.1q VLAN ID : Disabled -802.1q VLAN Priority : 0 -RMCP+ Cipher Suites : 1,2,3,6,7,8,11,12 -Cipher Suite Priv Max : XaaaXXaaaXXaaXX - : X=Cipher Suite Unused - : c=CALLBACK - : u=USER - : o=OPERATOR - : a=ADMIN - : O=OEM -Bad Password Threshold : Not Available -` -const lanPrint2 = "Set in Progress : Set Complete\nAuth Type Support : NONE MD2 MD5 PASSWORD \nAuth Type Enable : Callback : MD2 MD5 PASSWORD \n : User : MD2 MD5 PASSWORD \n : Operator : MD2 MD5 PASSWORD \n : Admin : MD2 MD5 PASSWORD \n : OEM : MD2 MD5 PASSWORD \nIP Address Source : DHCP Address\nIP Address : 192.168.2.53\nSubnet Mask : 255.255.255.0\nMAC Address : ac:1f:6b:73:c9:f0\nSNMP Community String : public\nIP Header : TTL=0x00 Flags=0x00 Precedence=0x00 TOS=0x00\nBMC ARP Control : ARP Responses Enabled, Gratuitous ARP Disabled\nDefault Gateway IP : 192.168.2.1\nDefault Gateway MAC : 00:00:00:00:00:00\nBackup Gateway IP : 0.0.0.0\nBackup Gateway MAC : 00:00:00:00:00:00\n802.1q VLAN ID : Disabled\n802.1q VLAN Priority : 0\nRMCP+ Cipher Suites : 1,2,3,6,7,8,11,12\nCipher Suite Priv Max : XaaaXXaaaXXaaXX\n : X=Cipher Suite Unused\n : c=CALLBACK\n : u=USER\n : o=OPERATOR\n : a=ADMIN\n : O=OEM\nBad Password Threshold : 0\nInvalid password disable: no\nAttempt Count Reset Int.: 0\nUser Lockout Interval : 0\n" - -func Test_getLanConfig(t *testing.T) { - tests := []struct { - name string - cmdOutput string - want map[string]string - }{ - { - name: "simple", - cmdOutput: lanPrint, - want: map[string]string{ - "IP Address": "10.248.36.246", - "Subnet Mask": "255.255.252.0", - "MAC Address": "0c:c4:7a:ed:3e:27", - }, - }, - { - name: "from real", - cmdOutput: lanPrint2, - want: map[string]string{ - "IP Address": "192.168.2.53", - "Subnet Mask": "255.255.255.0", - "MAC Address": "ac:1f:6b:73:c9:f0", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := output2Map(tt.cmdOutput) - for key, value := range tt.want { - if got[key] != value { - t.Errorf("getLanConfig() = %v, want %v", got[key], value) - } - } - }) - } -} -func TestGetLanConfig(t *testing.T) { - tests := []struct { - name string - want LanConfig - wantErr bool - }{ - // TODO: Add test cases. - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - i := &Ipmitool{Command: "/bin/true"} - got, err := i.GetLanConfig() - if (err != nil) != tt.wantErr { - t.Errorf("GetLanConfig() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetLanConfig() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestLanConfig_From(t *testing.T) { - type fields struct { - IP string - Mac string - } - tests := []struct { - name string - fields fields - input map[string]string - }{ - { - name: "simple", - fields: fields{ - IP: "192.168.2.53", - Mac: "ac:1f:6b:73:c9:f0", - }, - input: output2Map(lanPrint2), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &LanConfig{} - from(c, tt.input) - if c.IP != tt.fields.IP { - t.Errorf("IP is not as expected") - } - if c.Mac != tt.fields.Mac { - t.Errorf("Mac is not as expected") - } - }) - } -} diff --git a/pkg/sum/sum.go b/pkg/sum/sum.go deleted file mode 100644 index 4a80a08f..00000000 --- a/pkg/sum/sum.go +++ /dev/null @@ -1,346 +0,0 @@ -package sum - -import ( - "encoding/xml" - "fmt" - "github.com/metal-stack/metal-hammer/pkg/kernel" - "io/ioutil" - "os" - "os/exec" - "strings" - "syscall" - - log "github.com/inconshreveable/log15" - "github.com/metal-stack/metal-hammer/pkg/os/command" - "github.com/pkg/errors" - "golang.org/x/net/html/charset" -) - -type machineType int - -const ( - bigTwin machineType = iota - s2 -) - -const ( - biosCfgXML = "biosCfg.xml" - biosCfgUpdateXML = "biosCfgUpdate.xml" -) - -var ( - // SUM does not complain or fail if more boot options are given than actually available - uefiBootXMLFragmentTemplates = map[machineType]string{ - bigTwin: ` - - - - - - - - - - - - - - - - - - - -`, - s2: ` - - - - - - - - - - - - - - - - - - - -`, - } - - bootOrderXMLFragmentTemplates = map[machineType]string{ - bigTwin: ` - - - - - - - - - - - - -`, - s2: ` - - - - - - - - - - - - -`, - } -) - -type Menu struct { - XMLName xml.Name `xml:"Menu"` - Name string `xml:"name,attr"` - Settings []struct { - XMLName xml.Name `xml:"Setting"` - Name string `xml:"name,attr"` - Order string `xml:"order,attr,omitempty"` - SelectedOption string `xml:"selectedOption,attr"` - } `xml:"Setting"` - Menus []Menu `xml:"Menu"` -} - -type BiosCfg struct { - XMLName xml.Name `xml:"BiosCfg"` - Menus []Menu `xml:"Menu"` -} - -// Sum defines methods to interact with Supermicro Update Manager (SUM) -type Sum interface { - ConfigureBIOS() (bool, error) - EnsureBootOrder(bootloaderID string) error -} - -// sum is used to modify the BIOS config from the host OS. -type sum struct { - bootloaderID string - biosCfgXML string - biosCfg BiosCfg - machineType machineType - uefiNetworkBootOption string - secureBootEnabled bool -} - -func New() (Sum, error) { - return &sum{}, nil -} - -// ConfigureBIOS updates BIOS to UEFI boot and disables CSM-module if required. -// If returns whether machine needs to be rebooted or not. -func (s *sum) ConfigureBIOS() (bool, error) { - firmware := kernel.Firmware() - log.Info("firmware", "is", firmware) - - err := s.prepare() - if err != nil { - return false, err - } - - if firmware == "efi" && (s.machineType == s2 || s.secureBootEnabled) { // we cannot disable csm-support for S2 servers yet - return false, nil - } - - fragment := uefiBootXMLFragmentTemplates[s.machineType] - fragment = strings.ReplaceAll(fragment, "UEFI_NETWORK_BOOT_OPTION", s.uefiNetworkBootOption) - - return true, s.changeBiosCfg(fragment) -} - -// EnsureBootOrder ensures BIOS boot order so that boot from the given allocated OS image is attempted before PXE boot. -func (s *sum) EnsureBootOrder(bootloaderID string) error { - s.bootloaderID = bootloaderID - - err := s.prepare() - if err != nil { - log.Warn("BIOS updates for this machine type are intentionally not supported, skipping EnsureBootOrder", "error", err) - return nil - } - - ok := s.bootOrderProperlySet() - if ok { - log.Info("sum", "message", "boot order is already configured") - return nil - } - - fragment := bootOrderXMLFragmentTemplates[s.machineType] - fragment = strings.ReplaceAll(fragment, "BOOTLOADER_ID", s.bootloaderID) - fragment = strings.ReplaceAll(fragment, "UEFI_NETWORK_BOOT_OPTION", s.uefiNetworkBootOption) - - return s.changeBiosCfg(fragment) -} - -func (s *sum) prepare() error { - err := s.getCurrentBiosCfg() - if err != nil { - return err - } - - err = s.unmarshalBiosCfg() - if err != nil { - return errors.Wrapf(err, "unable to unmarshal BIOS configuration:\n%s", s.biosCfgXML) - } - - s.determineMachineType() - s.determineSecureBoot() - - return s.findUEFINetworkBootOption() -} - -func (s *sum) getCurrentBiosCfg() error { - err := s.execute("-c", "GetCurrentBiosCfg", "--file", biosCfgXML) - if err != nil { - return errors.Wrapf(err, "unable to get BIOS configuration via:%s -c GetCurrentBiosCfg --file %s", command.SUM, biosCfgXML) - } - - bb, err := ioutil.ReadFile(biosCfgXML) - if err != nil { - return errors.Wrapf(err, "unable to read file:%s", biosCfgXML) - } - - s.biosCfgXML = string(bb) - return nil -} - -func (s *sum) determineMachineType() { - for _, menu := range s.biosCfg.Menus { - if menu.Name != "Boot" { - continue - } - for _, setting := range menu.Settings { - if setting.Name == "UEFI Boot Option #1" { // not available in BigTwin BIOS - s.machineType = s2 - return - } - } - } - - s.machineType = bigTwin -} - -func (s *sum) determineSecureBoot() { - if s.machineType == s2 { // secure boot option is not available in S2 BIOS - return - } - for _, menu := range s.biosCfg.Menus { - if menu.Name != "Security" { - continue - } - for _, m := range menu.Menus { - if m.Name != "SMC Secure Boot Configuration" { - continue - } - for _, setting := range m.Settings { - if setting.Name == "Secure Boot" { - s.secureBootEnabled = setting.SelectedOption == "Enabled" - return - } - } - } - } -} - -func (s *sum) unmarshalBiosCfg() error { - s.biosCfg = BiosCfg{} - decoder := xml.NewDecoder(strings.NewReader(s.biosCfgXML)) - decoder.CharsetReader = charset.NewReaderLabel - return decoder.Decode(&s.biosCfg) -} - -func (s *sum) findUEFINetworkBootOption() error { - for _, menu := range s.biosCfg.Menus { - if menu.Name != "Boot" { - continue - } - for _, setting := range menu.Settings { - if strings.Contains(setting.SelectedOption, "UEFI Network") { - s.uefiNetworkBootOption = setting.SelectedOption - return nil - } - } - } - - return fmt.Errorf("cannot find PXE boot option in BIOS configuration:\n%s\n", s.biosCfgXML) -} - -func (s *sum) bootOrderProperlySet() bool { - if !s.checkBootOptionAt(1, s.bootloaderID) { - return false - } - if !s.checkBootOptionAt(2, s.uefiNetworkBootOption) { - return false - } - for i := 2; i <= 9; i++ { - if !s.checkBootOptionAt(i, "Disabled") { - return false - } - } - return true -} - -func (s *sum) checkBootOptionAt(index int, bootOption string) bool { - for _, menu := range s.biosCfg.Menus { - if menu.Name != "Boot" { - continue - } - for _, setting := range menu.Settings { - switch s.machineType { - case bigTwin: - if setting.Order != "1" { - continue - } - if setting.Name != fmt.Sprintf("Boot Option #%d", index) { - continue - } - case s2: - if setting.Name != fmt.Sprintf("UEFI Boot Option #%d", index) { - continue - } - } - - return strings.Contains(setting.SelectedOption, bootOption) - } - } - - return false -} - -func (s *sum) changeBiosCfg(fragment string) error { - err := ioutil.WriteFile(biosCfgUpdateXML, []byte(fragment), 0644) - if err != nil { - return err - } - - return s.execute("-c", "ChangeBiosCfg", "--file", biosCfgUpdateXML) -} - -func (s *sum) execute(args ...string) error { - cmd := exec.Command(command.SUM, args...) - cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr - cmd.SysProcAttr = &syscall.SysProcAttr{ - Credential: &syscall.Credential{ - Uid: uint32(0), - Gid: uint32(0), - Groups: []uint32{0}, - }, - } - return cmd.Run() -} diff --git a/pkg/sum/sum_test.go b/pkg/sum/sum_test.go deleted file mode 100644 index 0b5c74b7..00000000 --- a/pkg/sum/sum_test.go +++ /dev/null @@ -1,8347 +0,0 @@ -package sum - -import ( - "github.com/stretchr/testify/require" - "testing" -) - -func TestUnmarshalS2BiosCfg(t *testing.T) { - // given - s := &sum{} - s.biosCfgXML = testS2BiosCfg - - // when - err := s.unmarshalBiosCfg() - - // when - s.determineMachineType() - - // then - require.Equal(t, s2, s.machineType) - - // then - require.Nil(t, err) - - // when - err = s.findUEFINetworkBootOption() - - // then - require.Nil(t, err) - require.Equal(t, "UEFI Network:UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection", s.uefiNetworkBootOption) -} - -func TestUnmarshalBigTwinBiosCfg(t *testing.T) { - // given - s := &sum{} - s.biosCfgXML = testBigTwinBiosCfg - - // when - err := s.unmarshalBiosCfg() - - // when - s.determineMachineType() - - // then - require.Equal(t, bigTwin, s.machineType) - - // when - s.determineSecureBoot() - - // then - require.True(t, s.secureBootEnabled) - - // then - require.Nil(t, err) - - // when - err = s.findUEFINetworkBootOption() - - // then - require.Nil(t, err) - require.Equal(t, "UEFI Network:UEFI: PXE IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28", s.uefiNetworkBootOption) -} - -const ( - testS2BiosCfg = ` - - - - - - - - Supermicro X11SDV-8C-TP8F - BIOS Version(1.1a) - Build Date(05/17/2019) - - Memory Information - Total Memory(131072 MB) - - - - - - - - - - - - Checked - - - - - - - - - - - Force BIOS - - - - - - - - - - On - - - - - - - - - - Enabled - - - - - - - - - - Immediate - - - - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - Power Configuration - - - - - - - Disabled - - - - - - - - - - Instant Off - - - - - - - - - - - Last State - - - - - - - - - Processor Configuration - -------------------------------------------------- - Processor BSP Revision(50654 - SKX M0) - Processor Socket(CPU1) - Processor ID(00050654*) - Processor Frequency(2.300GHz) - Processor Max Ratio( 17H) - Processor Min Ratio( 0AH) - Microcode Revision(0200005E) - L1 Cache RAM( 64KB) - L2 Cache RAM( 1024KB) - L3 Cache RAM( 11264KB) - Processor 0 Version - Intel(R) Xeon(R) D-2146NT CPU @ 2.30GHz - - - - - - - - Enable - - - - - - 28 - 0 - 1 - 0 - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Unlock/Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - Enable - - - - - - - - Advanced Power Management Configuration - -------------------------------------------------- - - - - - - - - Energy Efficient - - - - - - - - - - OS Controls EPB - - - - - - - - - - - - - - Balanced Performance - - - - - - - - - - CPU P State Control - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - - Nominal - - - - - - - - - - - HW_ALL - - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - - Hardware PM State Control - - - - - - - - - - Disable - - - - - - - - - - CPU C State Control - - - - - - - - Disable - - - - - - - - - - - Auto - - - - - - - - - - - Enable - - - - - - - - - - - Package C State Control - - - - - - - - - - - - Auto - - - - - - - - - - CPU T State Control - - - - - - - - Disable - - - - - - - - - - - WARNING: Setting wrong values in below sections may cause - system to malfunction. - - - - - - - - - - -------------------------------------------------- - Integrated Memory Controller (iMC) - -------------------------------------------------- - - - - - - - - POR - - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - - - Auto - - - - - - - - - - Auto - - - - - - - - -------------------------------------------------- - DIMMA1: 2132MT/s Micron DRx4 32GB RDIMM - DIMMB1: 2132MT/s Micron DRx4 32GB RDIMM - DIMMD1: 2132MT/s Micron DRx4 32GB RDIMM - DIMME1: 2132MT/s Micron DRx4 32GB RDIMM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------------------------------------------- - Memory RAS Configuration Setup - -------------------------------------------------- - - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Two Rank - - - - - - - 32767 - 0 - 1 - 100 - - - - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Enable - - - - - - 24 - 0 - 0 - 24 - - - - - - - - - - - IIO Configuration - -------------------------------------------------- - - - - - - - - Disable - - - - - - - - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - CPU SLOT6 PCI-E 3.0 X16 - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x16) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU SLOT7 PCI-E 3.0 X8 - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x8) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - - - - - - - - No - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - to bring up the Intel® VT for Directed I/O (VT-d) Configuration menu.]]> - - Intel® VT for Directed I/O (VT-d) - -------------------------------------------------- - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - to bring up the Intel® VMD for Volume Management Device Configuration menu.]]> - - Intel® VMD technology - -------------------------------------------------- - - - - - - VMD Config for PStack0 - -------------------------------------------------- - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - IIO-PCIE Express Global Options - ======================================== - - - - - - - - No - - - - - - - - - - - USB Module Version(20) - - USB Devices:() - 2 Keyboards, 2 Mice, 4 Hubs - - - - - - - - - Enabled - - - - - - - - - - Disabled - - - - - - - - - - Enabled - - - - - - - - - - General ME Configuration - Oper. Firmware Version(0E:4.0.4.97) - Backup Firmware Version(N/A) - Recovery Firmware Version(0E:4.0.4.97) - ME Firmware Status #1(0x000F0245) - ME Firmware Status #2(0x8811C026) - Current State(Operational) - Error Code(No Error) - - - - - - PCH SATA Configuration - -------------------------------------------------- - - - - - - - - Enable - - - - - - - - - - AHCI - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Disable - - - - - - - - - - - Legacy - - - - - - SATA Port 0(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 1(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 2(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 3(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 4(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 5(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 6(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 7(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - - - - - - PCH sSATA Configuration - -------------------------------------------------- - - - - - - - - Enable - - - - - - - - - - AHCI - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Disable - - - - - - - - - - - Legacy - - - - - - sSATA Port 0(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 1(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 2(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 3(TOSHIBA MG06AC - 10000.8 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 4(TS64GMTS400S - 64.0 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 5([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - - - - - - P3:TOSHIBA MG06ACA10TE - P7:TOSHIBA MG06ACA10TE - - - - - - Unknown Device - - - - - - - - - PCI Bus Driver Version(A5.01.16) - - PCI Devices Common Settings: - - - - - - - Enabled - - - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - - - - - - - - - - 56T - - - - - - - - - - - - - - 256G - - - - - - - - - - - - - - - Auto - - - - - - - - - - - - - - 2G - - - - - - - - - - Vendor Defined Firmware - - - - - - - - - - Onboard - - - - - - - - - - CPU SLOT6 PCI-E 3.0 X16 - - - - - - - - - - - Disabled - - - - - - - - - - PCIE - - - - RSC-RR1U-E8 - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - Legacy - - - - - - - - - - - PXE - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - - Legacy - - - - - - - - - - - - - - Enabled - - - - - - - - - - Enabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - - - - - Disabled - - - - - - - 5 - 0 - 1 - 0 - - - - - - - 50 - 1 - 1 - 1 - - - - - - - - - - - - - - Super IO Configuration - - Super IO Chip(AST2500) - - - - - Serial Port 1 Configuration - - - - - Checked - - - - Device Settings(IO=3F8h; IRQ=4;) - - - - - - - - - - - - Auto - - - - - - - - - - Serial Port 2 Configuration - - - - - Checked - - - - Device Settings(IO=2F8h; IRQ=3;) - - - - - - - - - - - - Auto - - - - - - - - - - - - COM1 - - - - Unchecked - - - - - - - - - COM1 - Console Redirection Settings - - - - - - - - - - VT100+ - - - - - - - - - - - - - 115200 - - - - - - - - - - 8 - - - - - - - - - - - - - None - - - - - - - - - - 1 - - - - - - - - - - None - - - - - - - Checked - - - - - - - Unchecked - - - - - - - Checked - - - - - - - - - - 80x24 - - - - - - - - - - - - - - VT100 - - - - - - - - - - Always Enable - - - - - - - SOL - - - - Checked - - - - - - - - - SOL - Console Redirection Settings - - - - - - - - - - VT100+ - - - - - - - - - - - - - 115200 - - - - - - - - - - 8 - - - - - - - - - - - - - None - - - - - - - - - - 1 - - - - - - - - - - None - - - - - - - Checked - - - - - - - Unchecked - - - - - - - Checked - - - - - - - - - - 80x24 - - - - - - - - - - - - - - VT100 - - - - - - - - - - Always Enable - - - - - - - Legacy Console Redirection - - - - - - - COM1 - - - - - Serial Port for Out-of-Band Management/ - Windows Emergency Management Services (EMS) - - - - Unchecked - - - - - - - - - - - - - - - COM1 - - - - - - - - - - - - VT-UTF8 - - - - - - - - - - - - - 115200 - - - - - - - - - - - - None - - - - - Data Bits(8) - - Parity(None) - - Stop Bits(1) - - - - - - - - ACPI Settings - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - - - - - - Enabled - - - - - - - - - - Enabled - - - - - - - - - Configuration - - - - - - - Enable - - - - NO Security Device Found() - - - - - - - - - - - - - - - - - - - - - - - to change the SMBIOS Event Log configuration.]]> - - Enabling/Disabling Options - - - - - - - Enabled - - - - - Erasing Settings - - - - - - - - No - - - - - - - - - - - Do Nothing - - - - - - SMBIOS Event Log Standard Settings - - - - - - - Disabled - - - - - - - 255 - 1 - 1 - 1 - - - - - - - 99 - 0 - 1 - 60 - - - - - - NOTE: All values changed here do not take effect - until computer is restarted. - - - - to view the SMBIOS Event Log records.]]> - - DATE TIME ERROR CODE SEVERITY - - - - - - - Administrator Password(Not Installed) - - Administrator Password(Installed) - - User Password(Not Installed) - - User Password(Installed) - - - Password Description - - If the Administrator's / User's password is set, - then this only limits access to Setup and is - asked for when entering Setup. - Please set Administrator's password first in order - to set User's password, if clear Administrator's - password, the User's password will be cleared as well. - - The password length must be in the following range: - in the following range: - Minimum length(3) - Maximum length(20) - - - - Set Administrator Password - 3 - 20 - False - - - - - - - Set User Password - - 3 - 20 - False - - - - - - - - - - - Setup - - - - - - - - - - Enable - - - - HDD Security Configuration: - - - - - Boot Configuration - - - - - - - - - - - - - - - - - - - Dual - - - - - - - - - - Disabled - - - - - FIXED BOOT ORDER Priorities - - - - - - - - - - - - - - - UEFI Hard Disk:metal-ubuntu - - - - - - - - - - - - - - - - - - - UEFI AP:UEFI: Built-in EFI Shell - - - - - - - - - - - - - - - - - - - UEFI CD/DVD - - - - - - - - - - - - - - - - - - - UEFI USB Hard Disk - - - - - - - - - - - - - - - - - - - UEFI USB CD/DVD - - - - - - - - - - - - - - - - - - - UEFI USB Key - - - - - - - - - - - - - - - - - - - UEFI USB Floppy - - - - - - - - - - - - - - - - - - - UEFI USB Lan - - - - - - - - - - - - - - - - - - - UEFI Network:UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection - - - - - - - - - - - - - - - - - - Hard Disk - - - - - - - - - - - - - - - - - - CD/DVD - - - - - - - - - - - - - - - - - - USB Hard Disk - - - - - - - - - - - - - - - - - - USB CD/DVD - - - - - - - - - - - - - - - - - - USB Key - - - - - - - - - - - - - - - - - - USB Floppy - - - - - - - - - - - - - - - - - - USB Lan - - - - - - - - - - - - - - - - - - Network - - - - - - - - - - - - - - - - - - - - - - - - - - - Hard Disk - - - - - - - - - - - - - - - - - - - - - - - - - - - CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Hard Disk - - - - - - - - - - - - - - - - - - - - - - - - - - - USB CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Key - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Floppy - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Lan - - - - - - - - - - - - - - - - - - - - - - - - - - - Network - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI Hard Disk:metal-ubuntu - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Hard Disk - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Key - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Floppy - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Lan - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI Network:UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI AP:UEFI: Built-in EFI Shell - - - - - - - - - - - - - - - - - - - metal-ubuntu(SATA,Port:4) - - - - - - - - - - - UEFI OS(SATA,Port:4) - - - - - - - - - - - - - - - - UEFI: Built-in EFI Shell - - - - - - - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection(MAC,Address:ac1f6b7d7efa) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection(MAC,Address:ac1f6b7d7efb) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection(MAC,Address:ac1f6b7d7efc) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) I350 Gigabit Network Connection(MAC,Address:ac1f6b7d7efd) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) Ethernet Connection X722 for 10GBASE-T(MAC,Address:ac1f6b7d840a) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) Ethernet Connection X722 for 10GBASE-T(MAC,Address:ac1f6b7d840b) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) Ethernet Connection X722 for 10GbE SFP+(MAC,Address:ac1f6b7d840c) - - - - - - - - - - - - - - - - - UEFI: PXE IPv4 Intel(R) Ethernet Connection X722 for 10GbE SFP+(MAC,Address:ac1f6b7d840d) - - - - - - -` - testBigTwinBiosCfg = ` - - - - - - Supermicro X11DPT-B - BIOS Version(3.0a) - Build Date(02/20/2019) - CPLD Version(03.B0.09) - - Memory Information - Total Memory(98304 MB) - - - - - - - - - - - - Checked - - - - - - - - - - - Force BIOS - - - - - - - - - - On - - - - - - - - - - Enabled - - - - - - - - - - Immediate - - - - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - Power Configuration - - - - - - - Disabled - - - - - - - - - - - Last State - - - - - - - - - - Instant Off - - - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - - - - - Processor Configuration - -------------------------------------------------- - Processor BSP Revision(50654 - SKX U0) - Processor Socket(CPU1 | CPU2 ) - Processor ID(00050654* | 00050654 ) - Processor Frequency(2.100GHz | 2.100GHz) - Processor Max Ratio( 15H | 15H) - Processor Min Ratio( 08H | 08H) - Microcode Revision(02000057 | 02000057) - L1 Cache RAM( 64KB | 64KB) - L2 Cache RAM( 1024KB | 1024KB) - L3 Cache RAM( 11264KB | 11264KB) - Processor 0 Version - Intel(R) Xeon(R) Silver 4110 CPU @ 2.10GHz - Processor 1 Version - Intel(R) Xeon(R) Silver 4110 CPU @ 2.10GHz - - - - - - - - Enable - - - - - - 28 - 0 - 1 - 0 - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Unlock/Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - Enable - - - - - - - - Advanced Power Management Configuration - -------------------------------------------------- - - - - - - - - Energy Efficient - - - - - - - - - - OS Controls EPB - - - - - - - - - - - - - - - Balanced Performance - - - - - - - - - - CPU P State Control - - - - - - - - Enable - - - - - - - - - - - HW_ALL - - - - - - - - - - - Enable - - - - - - - - - - - Hardware PM State Control - - - - - - - - - - Disable - - - - - - - - - - CPU C State Control - - - - - - - - Disable - - - - - - - - - - - Auto - - - - - - - - - - - Enable - - - - - - - - - - - Package C State Control - - - - - - - - - - - - Auto - - - - - - - - - - CPU T State Control - - - - - - - - Disable - - - - - - - - - - - WARNING: Setting wrong values in below sections may cause - system to malfunction. - - - - - - - - - UPI Configuration - -------------------------------------------------- - Number of CPU(2) - Number of Active UPI Link(2) - Current UPI Link Speed(Fast) - Current UPI Link Frequency(9.6 GT/s) - UPI Global MMIO Low Base / Limit(90000000 / FBFFFFFF) - UPI Global MMIO High Base / Limit(0000000000000000 / 00000000FFFFFFFF) - UPI Pci-e Configuration Base / Size(80000000 / 10000000) - - - - - - - Topology Precedence - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - Enable - - - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - - - - Enable - - - - - - - - - - - Auto - - - - - - - - - - -------------------------------------------------- - Integrated Memory Controller (iMC) - -------------------------------------------------- - - - - - - - - POR - - - - - - - - - - - - Auto - - - - - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - - - Auto - - - - - - - - - - Disable - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - - - - Auto - - - - - - - - -------------------------------------------------- - P1 DIMMA1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P1 DIMMB1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P1 DIMMC1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P1 DIMMD1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P1 DIMME1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P1 DIMMF1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P2 DIMMA1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P2 DIMMB1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P2 DIMMC1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P2 DIMMD1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P2 DIMME1: 2400MT/s Micron Technology DRx8 8GB RDIMM - P2 DIMMF1: 2400MT/s Micron Technology DRx8 8GB RDIMM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------------------------------------------- - Memory RAS Configuration Setup - -------------------------------------------------- - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Two Rank - - - - - - - 32767 - 1 - 1 - 100 - - - - - - - - - - Disable - - - - - - - - - - Enable - - - - - - 24 - 0 - 0 - 24 - - - - - - - - - - - IIO Configuration - -------------------------------------------------- - - - - - - - - Disable - - - - - - - - - - - - - - - - - - Auto - - - - - - - - - - - - - - Auto - - - - - - - - - - - - - - Auto - - - - - - - - CPU1 PcieBr0D00F0 - Port 0/DMI - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Linked as x4) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Gen 3 (8.0 GT/s)) - - - - - - - - Auto - - - - - - - - - CPU1 PcieBr1D00F0 - Port 1A - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Linked as x8) - PCI-E Port Link Max(Max Width x16) - PCI-E Port Link Speed(Gen 3 (8.0 GT/s)) - - - - - - - - Auto - - - - - - - - - CPU1 PcieBr2D00F0 - Port 2A - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Linked as x4) - PCI-E Port Link Max(Max Width x16) - PCI-E Port Link Speed(Gen 2 (5.0 GT/s)) - - - - - - - - Auto - - - - - - - - - CPU1 PcieBr3D00F0 - Port 3A - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x8) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU1 PcieBr3D02F0 - Port 3C - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU1 PcieBr3D03F0 - Port 3D - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - - - - - - - - - - - - Auto - - - - - - - - - - - - - - Auto - - - - - - - - - - - - - - Auto - - - - - - - - CPU2 PcieBr1D00F0 - Port 1A - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x8) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU2 PcieBr1D02F0 - Port 1C - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x8) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU2 PcieBr2D00F0 - Port 2A - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x16) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU2 PcieBr3D00F0 - Port 3A - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Linked as x4) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Gen 3 (8.0 GT/s)) - - - - - - - - Auto - - - - - - - - - CPU2 PcieBr3D01F0 - Port 3B - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Linked as x4) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Gen 3 (8.0 GT/s)) - - - - - - - - Auto - - - - - - - - - CPU2 PcieBr3D02F0 - Port 3C - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - CPU2 PcieBr3D03F0 - Port 3D - -------------------------------------------------- - - - - - - - - - - Auto - - - - PCI-E Port Link Status(Link Did Not Train) - PCI-E Port Link Max(Max Width x4) - PCI-E Port Link Speed(Link Did Not Train) - - - - - - - - Auto - - - - - - - - - - - - - - - - No - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - to bring up the Intel® VT for Directed I/O (VT-d) Configuration menu.]]> - - Intel® VT for Directed I/O (VT-d) - -------------------------------------------------- - - - - - - - - Enable - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - to bring up the Intel® VMD for Volume Management Device Configuration menu.]]> - - Intel® VMD Technology - -------------------------------------------------- - - - - - - VMD Config for PStack1 - -------------------------------------------------- - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - VMD Config for PStack2 - -------------------------------------------------- - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - - VMD Config for PStack0 - -------------------------------------------------- - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - VMD Config for PStack1 - -------------------------------------------------- - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - VMD Config for PStack2 - -------------------------------------------------- - - - - - - - Disable - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - - Disable - - - - - - - - - - IIO-PCIE Express Global Options - ======================================== - - - - - - - - No - - - - - - - - - - - USB Module Version(21) - - USB Devices:() - 1 Keyboard, 1 Mouse, 1 Hub - - - - - - - - - Enabled - - - - - - - - - - Enabled - - - - - - - - - - Enabled - - - - - - - - - - Disable - - - - - - - - - - General ME Configuration - Oper. Firmware Version(4.1.3.239) - Backup Firmware Version(N/A) - Recovery Firmware Version(4.1.3.239) - ME Firmware Status #1(0x000F0255) - ME Firmware Status #2(0x88114026) - Current State(Operational) - Error Code(No Error) - - - - - - PCH SATA Configuration - -------------------------------------------------- - - - - - - - - Enable - - - - - - - - - - AHCI - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Disable - - - - - - - - - - - Legacy - - - - - - SATA Port 0([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 1([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 2([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 3([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 4([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 5([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 6(SuperMicro SSD - 63.3 GB) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - SATA Port 7([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - - - - - - PCH sSATA Configuration - -------------------------------------------------- - - - - - - - - Enable - - - - - - - - - - AHCI - - - - - - - - - - - Enable - - - - - - - - - - - Enable - - - - - - - - - - - Disable - - - - - - - - - - - Legacy - - - - - - sSATA Port 0([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 1([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 2([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 3([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 4([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - sSATA Port 5([Not Installed]) - - - - - - - Enable - - - - - - - - - - Disable - - - - - - - - - - Hard Disk Drive - - - - - - - - - PCI Bus Driver Version(A5.01.18) - - PCI Devices Common Settings: - - - - - - - Enabled - - - - - - - - - - Disabled - - - - - - - - - - - - - - - 56T - - - - - - - - - - - - - - 256G - - - - - - - - - - - - - - - Auto - - - - - - - - - - - - - - 2G - - - - - - - - - - Vendor Defined Firmware - - - - - - - - - - Onboard - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - - Legacy - - - - - - - - - - Enabled - - - - - - - - - - - - EFI - - - - - - - - - - - - EFI - - - - - - - - - - - - EFI - - - - - - - - - - - - EFI - - - - - - - - - - - Legacy - - - - - - - - - - - - Super IO Configuration - - Super IO Chip(AST2500) - - - - - Serial Port 1 Configuration - - - - - Checked - - - - Device Settings(IO=3F8h; IRQ=4;) - - - - - - - - - - - - Auto - - - - - - - - - - Serial Port 2 Configuration - - - - - Checked - - - - Device Settings(IO=2F8h; IRQ=3;) - - - - - - - - - - - - Auto - - - - - - - - - - - SOL - - - - - - - - - - - COM1 - - - - Unchecked - - - - - - - - - COM1 - Console Redirection Settings - - - - - - - - - - VT100+ - - - - - - - - - - - - - 115200 - - - - - - - - - - 8 - - - - - - - - - - - - - None - - - - - - - - - - 1 - - - - - - - - - - None - - - - - - - Checked - - - - - - - Unchecked - - - - - - - Checked - - - - - - - - - - 80x25 - - - - - - - - - - - - - - VT100 - - - - - - - - - - Always Enable - - - - - - - SOL/COM2 - - - - Checked - - - - - - - - - SOL/COM2 - Console Redirection Settings - - - - - - - - - - VT100+ - - - - - - - - - - - - - 115200 - - - - - - - - - - 8 - - - - - - - - - - - - - None - - - - - - - - - - 1 - - - - - - - - - - None - - - - - - - Checked - - - - - - - Unchecked - - - - - - - Checked - - - - - - - - - - 80x25 - - - - - - - - - - - - - - VT100 - - - - - - - - - - Always Enable - - - - - - - Legacy Console Redirection - - - - - - - COM1 - - - - - Serial Port for Out-of-Band Management/ - Windows Emergency Management Services (EMS) - - - - Unchecked - - - - - - - - - - - - - - - COM1 - - - - - - - - - - - - VT-UTF8 - - - - - - - - - - - - - 115200 - - - - - - - - - - - - None - - - - - Data Bits(8) - - Parity(None) - - Stop Bits(1) - - - - - - - - ACPI Settings - - - - - - - - Disabled - - - - - - - - - - Disabled - - - - - - - - - - Enabled - - - - - - - - - - Enabled - - - - - - - - - - Enabled - - - - - - - - - Configuration - - - - - - - Enable - - - - - - - - - - Disabled - - - - NO Security Device Found() - - - - - - HTTP BOOT Configuration - - - - - - - Disabled - - - - - - 0 - 75 - - - False - - - - - - 0 - 80 - - - False - - - - - - - - - - - - - - - - - - - - - - to change the SMBIOS Event Log configuration.]]> - - Enabling/Disabling Options - - - - - - - Enabled - - - - - Erasing Settings - - - - - - - - No - - - - - - - - - - - Do Nothing - - - - - - SMBIOS Event Log Standard Settings - - - - - - - Disabled - - - - - - - 255 - 1 - 1 - 1 - - - - - - - 99 - 0 - 1 - 60 - - - - - - NOTE: All values changed here do not take effect - until computer is restarted. - - - - to view the SMBIOS Event Log records.]]> - - DATE TIME ERROR CODE SEVERITY - - - - - - - - - - Administrator Password(Not Installed) - - Administrator Password(Installed) - - User Password(Not Installed) - - User Password(Installed) - - - Password Description - - If the Administrator's / User's password is set, - then this only limits access to Setup and is - asked for when entering Setup. - Please set Administrator's password first in order - to set User's password, if clear Administrator's - password, the User's password will be cleared as well. - - The password length must be - in the following range: - Minimum length(3) - Maximum length(20) - - - - Set Administrator Password - 3 - 20 - False - - - - - - - Set User Password - - 3 - 20 - False - - - - - - - - - - - Setup - - - - - - - - - HDD Name(SuperMicro SSD) - HDD Serial Number(SMC0515D93017CHJ5126) - Security Erase Mode(SAT3 Supported) - Estimated Time(4 Minutes) - HDD User Pwd Status:(NOT INSTALLED) - - - - - - - - Disable - - - - - - 0 - 32 - - - False - - - - - - - - - - - - - - - - - Disabled - - - - - - - - - - - - Disabled - - - - System Mode(Setup) - Secure Boot(Not Active) - - - - - - - - - - - - - Setup - - - - - HDD Security Configuration: - - - - - HDD Password Description : - - Allow Access to Set, Modify and Clear HardDisk User and Master Passwords. - User Password need to be installed for Enabling Security. - Master Password can be Modified only when successfully unlocked with Master Password in POST. - If the 'Set HDD Password' option is grayed out, do power cycle to enablethe option again. - - - HDD PASSWORD CONFIGURATION: - - Security Supported :(Yes) - Security Supported :(No) - Security Enabled :(Yes) - Security Enabled :(No) - Security Locked :(Yes) - Security Locked :(No) - Security Frozen :(Yes) - Security Frozen :(No) - HDD User Pwd Status:(INSTALLED) - HDD User Pwd Status:(NOT INSTALLED) - HDD Master Pwd Status :(INSTALLED) - HDD Master Pwd Status :(NOT INSTALLED) - - - - - - - - - - Boot Configuration - - - - - - - - - DUAL - - - - - - - - - - Disabled - - - - - FIXED BOOT ORDER Priorities - - - - - - - - - - - - - - - UEFI Hard Disk - - - - - - - - - - - - - - - - - - - UEFI AP - - - - - - - - - - - - - - - - - - - UEFI CD/DVD - - - - - - - - - - - - - - - - - - - UEFI USB Hard Disk - - - - - - - - - - - - - - - - - - - UEFI USB CD/DVD - - - - - - - - - - - - - - - - - - - UEFI USB Key - - - - - - - - - - - - - - - - - - - UEFI USB Floppy - - - - - - - - - - - - - - - - - - - UEFI USB Lan - - - - - - - - - - - - - - - - - - - UEFI Network:UEFI: PXE IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28 - - - - - - - - - - - - - - - - - - Hard Disk: SuperMicro SSD - - - - - - - - - - - - - - - - - - CD/DVD - - - - - - - - - - - - - - - - - - USB Hard Disk - - - - - - - - - - - - - - - - - - USB CD/DVD - - - - - - - - - - - - - - - - - - USB Key - - - - - - - - - - - - - - - - - - USB Floppy - - - - - - - - - - - - - - - - - - USB Lan - - - - - - - - - - - - - - - - - - Network - - - - - - - - - - - - - - - - - - - - - - - - - - - Hard Disk: SuperMicro SSD - - - - - - - - - - - - - - - - - - - - - - - - - - - CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Hard Disk - - - - - - - - - - - - - - - - - - - - - - - - - - - USB CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Key - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Floppy - - - - - - - - - - - - - - - - - - - - - - - - - - - USB Lan - - - - - - - - - - - - - - - - - - - - - - - - - - - Network - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI Hard Disk - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Hard Disk - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB CD/DVD - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Key - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Floppy - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI USB Lan - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI Network:UEFI: PXE IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28 - - - - - - - - - - - - - - - - - - - - - - - - - - - UEFI AP - - - - - - - - - - - - - - - - - - UEFI: Built-in EFI Shell - - - - - - - - - - - - - - - - - - - UEFI: PXE IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28(MAC,Address:ac1f6b7aeb76) - - - - - - - - - - - - - UEFI: PXE IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28(MAC,Address:ac1f6b7aeb77) - - - - - - - - - - - - - UEFI: HTTP IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28(MAC,Address:ac1f6b7aeb76) - - - - - - - - - - - - - UEFI: HTTP IP4 Intel(R) Ethernet Controller XXV710 for 25GbE SFP28(MAC,Address:ac1f6b7aeb77) - - - - - - - - - - - - - - - - ISATA P6: SuperMicro SSD (SATA,Port:6) - - - - - -` -) diff --git a/pkg/uuid/uuid.go b/pkg/uuid/uuid.go deleted file mode 100644 index b1b359b4..00000000 --- a/pkg/uuid/uuid.go +++ /dev/null @@ -1,48 +0,0 @@ -package uuid - -import ( - "fmt" - "io/ioutil" - "os" - "strings" - - guuid "github.com/google/uuid" - log "github.com/inconshreveable/log15" -) - -const dmiUUID = "/sys/class/dmi/id/product_uuid" -const dmiSerial = "/sys/class/dmi/id/product_serial" - -// MachineUUID calculates a unique uuid for this (hardware) machine -func MachineUUID() string { - return machineUUID(ioutil.ReadFile) -} - -func machineUUID(readFileFunc func(filename string) ([]byte, error)) string { - if _, err := os.Stat(dmiUUID); !os.IsNotExist(err) { - productUUID, err := readFileFunc(dmiUUID) - if err != nil { - log.Error("error getting product_uuid", "error", err) - } else { - log.Info("create UUID from", "source", dmiUUID) - return strings.TrimSpace(string(productUUID)) - } - } - - if _, err := os.Stat(dmiSerial); !os.IsNotExist(err) { - productSerial, err := readFileFunc(dmiSerial) - if err != nil { - log.Error("error getting product_serial", "error", err) - } else { - productSerialBytes, err := guuid.FromBytes([]byte(fmt.Sprintf("%16s", string(productSerial)))) - if err != nil { - log.Error("error converting product_serial to uuid", "error", err) - } else { - log.Info("create UUID from", "source", dmiSerial) - return strings.TrimSpace(productSerialBytes.String()) - } - } - } - log.Error("no valid UUID found", "return uuid", "00000000-0000-0000-0000-000000000000") - return "00000000-0000-0000-0000-000000000000" -} diff --git a/pkg/uuid/uuid_test.go b/pkg/uuid/uuid_test.go deleted file mode 100644 index a8a7c0d2..00000000 --- a/pkg/uuid/uuid_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package uuid - -import ( - "testing" -) - -func TestMachineUUID(t *testing.T) { - - readFileFunc := func(filename string) ([]byte, error) { - return []byte("4C4C4544-0042-4810-8056-B4C04F395332"), nil - } - - tests := []struct { - name string - want string - }{ - { - name: "TestMachineUUID Test 1", - want: "4C4C4544-0042-4810-8056-B4C04F395332", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := machineUUID(readFileFunc); got != tt.want { - t.Errorf("MachineUUID() = %v, want %v", got, tt.want) - } - }) - } -}