diff --git a/cmd/bootstrap-peer-server.go b/cmd/bootstrap-peer-server.go index 552e2e5ce..ebb60a919 100644 --- a/cmd/bootstrap-peer-server.go +++ b/cmd/bootstrap-peer-server.go @@ -19,9 +19,13 @@ package cmd import ( "context" + "crypto/md5" + "encoding/hex" "errors" "fmt" + "io" "math/rand" + "os" "reflect" "strings" "sync" @@ -43,10 +47,15 @@ type ServerSystemConfig struct { NEndpoints int CmdLines []string MinioEnv map[string]string + Checksum string } // Diff - returns error on first difference found in two configs. func (s1 *ServerSystemConfig) Diff(s2 *ServerSystemConfig) error { + if s1.Checksum != s2.Checksum { + return fmt.Errorf("Expected MinIO binary checksum: %s, seen: %s", s1.Checksum, s2.Checksum) + } + ns1 := s1.NEndpoints ns2 := s2.NEndpoints if ns1 != ns2 { @@ -82,7 +91,7 @@ func (s1 *ServerSystemConfig) Diff(s2 *ServerSystemConfig) error { extra = append(extra, k) } } - msg := "Expected same MINIO_ environment variables and values across all servers: " + msg := "Expected MINIO_* environment name and values across all servers to be same: " if len(missing) > 0 { msg += fmt.Sprintf(`Missing environment values: %v. `, missing) } @@ -120,7 +129,7 @@ func getServerSystemCfg() *ServerSystemConfig { } envValues[envK] = logger.HashString(env.Get(envK, "")) } - scfg := &ServerSystemConfig{NEndpoints: globalEndpoints.NEndpoints(), MinioEnv: envValues} + scfg := &ServerSystemConfig{NEndpoints: globalEndpoints.NEndpoints(), MinioEnv: envValues, Checksum: binaryChecksum} var cmdLines []string for _, ep := range globalEndpoints { cmdLines = append(cmdLines, ep.CmdLine) @@ -167,6 +176,18 @@ func (client *bootstrapRESTClient) String() string { return client.gridConn.String() } +var binaryChecksum = getBinaryChecksum() + +func getBinaryChecksum() string { + mw := md5.New() + b, err := os.Open(os.Args[0]) + if err == nil { + defer b.Close() + io.Copy(mw, b) + } + return hex.EncodeToString(mw.Sum(nil)) +} + func verifyServerSystemConfig(ctx context.Context, endpointServerPools EndpointServerPools, gm *grid.Manager) error { srcCfg := getServerSystemCfg() clnts := newBootstrapRESTClients(endpointServerPools, gm) @@ -196,7 +217,7 @@ func verifyServerSystemConfig(ctx context.Context, endpointServerPools EndpointS err := clnt.Verify(ctx, srcCfg) mu.Lock() if err != nil { - bootstrapTraceMsg(fmt.Sprintf("clnt.Verify: %v, endpoint: %s", err, clnt)) + bootstrapTraceMsg(fmt.Sprintf("bootstrapVerify: %v, endpoint: %s", err, clnt)) if !isNetworkError(err) { bootLogOnceIf(context.Background(), fmt.Errorf("%s has incorrect configuration: %w", clnt, err), "incorrect_"+clnt.String()) incorrectConfigs = append(incorrectConfigs, fmt.Errorf("%s has incorrect configuration: %w", clnt, err)) diff --git a/cmd/bootstrap-peer-server_gen.go b/cmd/bootstrap-peer-server_gen.go index 77f4cde1d..ada471c79 100644 --- a/cmd/bootstrap-peer-server_gen.go +++ b/cmd/bootstrap-peer-server_gen.go @@ -79,6 +79,12 @@ func (z *ServerSystemConfig) DecodeMsg(dc *msgp.Reader) (err error) { } z.MinioEnv[za0002] = za0003 } + case "Checksum": + z.Checksum, err = dc.ReadString() + if err != nil { + err = msgp.WrapError(err, "Checksum") + return + } default: err = dc.Skip() if err != nil { @@ -92,9 +98,9 @@ func (z *ServerSystemConfig) DecodeMsg(dc *msgp.Reader) (err error) { // EncodeMsg implements msgp.Encodable func (z *ServerSystemConfig) EncodeMsg(en *msgp.Writer) (err error) { - // map header, size 3 + // map header, size 4 // write "NEndpoints" - err = en.Append(0x83, 0xaa, 0x4e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73) + err = en.Append(0x84, 0xaa, 0x4e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73) if err != nil { return } @@ -142,15 +148,25 @@ func (z *ServerSystemConfig) EncodeMsg(en *msgp.Writer) (err error) { return } } + // write "Checksum" + err = en.Append(0xa8, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d) + if err != nil { + return + } + err = en.WriteString(z.Checksum) + if err != nil { + err = msgp.WrapError(err, "Checksum") + return + } return } // MarshalMsg implements msgp.Marshaler func (z *ServerSystemConfig) MarshalMsg(b []byte) (o []byte, err error) { o = msgp.Require(b, z.Msgsize()) - // map header, size 3 + // map header, size 4 // string "NEndpoints" - o = append(o, 0x83, 0xaa, 0x4e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73) + o = append(o, 0x84, 0xaa, 0x4e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73) o = msgp.AppendInt(o, z.NEndpoints) // string "CmdLines" o = append(o, 0xa8, 0x43, 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x73) @@ -165,6 +181,9 @@ func (z *ServerSystemConfig) MarshalMsg(b []byte) (o []byte, err error) { o = msgp.AppendString(o, za0002) o = msgp.AppendString(o, za0003) } + // string "Checksum" + o = append(o, 0xa8, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d) + o = msgp.AppendString(o, z.Checksum) return } @@ -241,6 +260,12 @@ func (z *ServerSystemConfig) UnmarshalMsg(bts []byte) (o []byte, err error) { } z.MinioEnv[za0002] = za0003 } + case "Checksum": + z.Checksum, bts, err = msgp.ReadStringBytes(bts) + if err != nil { + err = msgp.WrapError(err, "Checksum") + return + } default: bts, err = msgp.Skip(bts) if err != nil { @@ -266,5 +291,6 @@ func (z *ServerSystemConfig) Msgsize() (s int) { s += msgp.StringPrefixSize + len(za0002) + msgp.StringPrefixSize + len(za0003) } } + s += 9 + msgp.StringPrefixSize + len(z.Checksum) return }