diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index b9084368a..ddac0cbea 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -3196,6 +3196,7 @@ func (a adminAPIHandlers) InspectDataHandler(w http.ResponseWriter, r *http.Requ return } } + addErr := func(msg string) {} // Write a version for making *incompatible* changes. // The AdminClient will reject any version it does not know. @@ -3235,6 +3236,11 @@ func (a adminAPIHandlers) InspectDataHandler(w http.ResponseWriter, r *http.Requ bugLogIf(ctx, stream.AddError(err.Error())) return } + addErr = func(msg string) { + inspectZipW.Close() + encStream.Close() + stream.AddError(msg) + } defer encStream.Close() inspectZipW = zip.NewWriter(encStream) @@ -3315,18 +3321,6 @@ func (a adminAPIHandlers) InspectDataHandler(w http.ResponseWriter, r *http.Requ } return nil } - err := o.GetRawData(ctx, volume, file, rawDataFn) - if !errors.Is(err, errFileNotFound) { - adminLogIf(ctx, err) - } - - // save the format.json as part of inspect by default - if !(volume == minioMetaBucket && file == formatConfigFile) { - err = o.GetRawData(ctx, minioMetaBucket, formatConfigFile, rawDataFn) - } - if !errors.Is(err, errFileNotFound) { - adminLogIf(ctx, err) - } // save args passed to inspect command var sb bytes.Buffer @@ -3339,6 +3333,24 @@ func (a adminAPIHandlers) InspectDataHandler(w http.ResponseWriter, r *http.Requ sb.WriteString("\n") adminLogIf(ctx, embedFileInZip(inspectZipW, "inspect-input.txt", sb.Bytes(), 0o600)) + err := o.GetRawData(ctx, volume, file, rawDataFn) + if err != nil { + if errors.Is(err, errFileNotFound) { + addErr("GetRawData: No files matched the given pattern") + return + } + embedFileInZip(inspectZipW, "GetRawData-err.txt", []byte(err.Error()), 0o600) + adminLogIf(ctx, err) + } + + // save the format.json as part of inspect by default + if !(volume == minioMetaBucket && file == formatConfigFile) { + err = o.GetRawData(ctx, minioMetaBucket, formatConfigFile, rawDataFn) + } + if !errors.Is(err, errFileNotFound) { + adminLogIf(ctx, err) + } + scheme := "https" if !globalIsTLS { scheme = "http" diff --git a/cmd/endpoint-ellipses.go b/cmd/endpoint-ellipses.go index 3b812085b..c24183746 100644 --- a/cmd/endpoint-ellipses.go +++ b/cmd/endpoint-ellipses.go @@ -477,7 +477,7 @@ func mergeDisksLayoutFromArgs(args []string, ctxt *serverCtxt) (err error) { } ctxt.Layout = disksLayout{ legacy: true, - pools: []poolDisksLayout{{layout: setArgs}}, + pools: []poolDisksLayout{{layout: setArgs, cmdline: strings.Join(args, " ")}}, } return } diff --git a/docs/debugging/inspect/decrypt-v1.go b/docs/debugging/inspect/decrypt-v1.go index fc7e6cedd..081f20bd6 100644 --- a/docs/debugging/inspect/decrypt-v1.go +++ b/docs/debugging/inspect/decrypt-v1.go @@ -27,7 +27,7 @@ import ( "github.com/secure-io/sio-go" ) -func extractInspectV1(keyHex string, r io.Reader, w io.Writer) error { +func extractInspectV1(keyHex string, r io.Reader, w io.Writer, okMsg string) error { id, err := hex.DecodeString(keyHex[:8]) if err != nil { return err @@ -51,5 +51,8 @@ func extractInspectV1(keyHex string, r io.Reader, w io.Writer) error { nonce := make([]byte, stream.NonceSize()) encr := stream.DecryptReader(r, nonce, nil) _, err = io.Copy(w, encr) + if err == nil { + fmt.Println(okMsg) + } return err } diff --git a/docs/debugging/inspect/decrypt-v2.go b/docs/debugging/inspect/decrypt-v2.go index 17e34bbb9..a38aae4a5 100644 --- a/docs/debugging/inspect/decrypt-v2.go +++ b/docs/debugging/inspect/decrypt-v2.go @@ -26,7 +26,11 @@ import ( "github.com/minio/madmin-go/v3/estream" ) -func extractInspectV2(pk []byte, r io.Reader, w io.Writer) error { +type keepFileErr struct { + error +} + +func extractInspectV2(pk []byte, r io.Reader, w io.Writer, okMsg string) error { privKey, err := bytesToPrivateKey(pk) if err != nil { return fmt.Errorf("decoding key returned: %w", err) @@ -45,11 +49,14 @@ func extractInspectV2(pk []byte, r io.Reader, w io.Writer) error { sr.SkipEncrypted(true) return sr.DebugStream(os.Stdout) } - + extracted := false for { stream, err := sr.NextStream() if err != nil { if err == io.EOF { + if extracted { + return nil + } return errors.New("no data found on stream") } if errors.Is(err, estream.ErrNoKey) { @@ -61,14 +68,22 @@ func extractInspectV2(pk []byte, r io.Reader, w io.Writer) error { } continue } + if extracted { + return keepFileErr{fmt.Errorf("next stream: %w", err)} + } return fmt.Errorf("next stream: %w", err) } if stream.Name == "inspect.zip" { + if extracted { + return keepFileErr{errors.New("multiple inspect.zip streams found")} + } _, err := io.Copy(w, stream) if err != nil { return fmt.Errorf("reading inspect stream: %w", err) } - return nil + fmt.Println(okMsg) + extracted = true + continue } if err := stream.Skip(); err != nil { return fmt.Errorf("stream skip: %w", err) diff --git a/docs/debugging/inspect/main.go b/docs/debugging/inspect/main.go index 4b363110c..2cd97c7c0 100644 --- a/docs/debugging/inspect/main.go +++ b/docs/debugging/inspect/main.go @@ -24,6 +24,7 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "errors" "flag" "fmt" "io" @@ -117,18 +118,23 @@ func main() { fatalErr(err) // Decrypt the inspect data + msg := fmt.Sprintf("output written to %s", outputFileName) + switch { case *keyHex != "": - err = extractInspectV1(*keyHex, input, output) + err = extractInspectV1(*keyHex, input, output, msg) case len(privateKey) != 0: - err = extractInspectV2(privateKey, input, output) + err = extractInspectV2(privateKey, input, output, msg) } output.Close() if err != nil { - os.Remove(outputFileName) + + var keep keepFileErr + if !errors.As(err, &keep) { + os.Remove(outputFileName) + } fatalErr(err) } - fmt.Println("output written to", outputFileName) // Export xl.meta to stdout if *export {