github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/docs/debugging/healing-bin/main.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package main
    19  
    20  import (
    21  	"archive/zip"
    22  	"bytes"
    23  	"encoding/json"
    24  	"fmt"
    25  	"io"
    26  	"log"
    27  	"os"
    28  	"strings"
    29  
    30  	"github.com/minio/cli"
    31  	"github.com/tinylib/msgp/msgp"
    32  )
    33  
    34  func main() {
    35  	app := cli.NewApp()
    36  	app.Copyright = "MinIO, Inc."
    37  	app.Usage = "healing.bin to JSON"
    38  	app.HideVersion = true
    39  	app.HideHelpCommand = true
    40  	app.CustomAppHelpTemplate = `NAME:
    41    {{.Name}} - {{.Usage}}
    42  
    43  USAGE:
    44    {{.Name}} {{if .VisibleFlags}}[FLAGS]{{end}} [HEALINGBINFILE|INSPECTZIPFILE]
    45  
    46  files ending in '.zip' will be searched for '.healing.bin files recursively and
    47  printed together as a single JSON.
    48  
    49  FLAGS:
    50    {{range .VisibleFlags}}{{.}}
    51    {{end}}
    52  `
    53  	app.Flags = []cli.Flag{}
    54  	app.Action = func(c *cli.Context) error {
    55  		if !c.Args().Present() {
    56  			cli.ShowAppHelpAndExit(c, 1) // last argument is exit code
    57  		}
    58  
    59  		ht := make(map[string]map[string]interface{})
    60  		file := c.Args().Get(0)
    61  		if strings.HasSuffix(file, ".zip") {
    62  			var sz int64
    63  			f, err := os.Open(file)
    64  			if err != nil {
    65  				return err
    66  			}
    67  			if st, err := f.Stat(); err == nil {
    68  				sz = st.Size()
    69  			}
    70  			defer f.Close()
    71  			zr, err := zip.NewReader(f, sz)
    72  			if err != nil {
    73  				return err
    74  			}
    75  			for _, file := range zr.File {
    76  				if !file.FileInfo().IsDir() && strings.HasSuffix(file.Name, ".healing.bin") {
    77  					r, err := file.Open()
    78  					if err != nil {
    79  						return err
    80  					}
    81  
    82  					b, err := io.ReadAll(r)
    83  					if err != nil {
    84  						return err
    85  					}
    86  					buf := bytes.NewBuffer(nil)
    87  					if _, err = msgp.CopyToJSON(buf, bytes.NewReader(b)); err != nil {
    88  						return err
    89  					}
    90  
    91  					dec := json.NewDecoder(buf)
    92  					// Use number to preserve integers.
    93  					dec.UseNumber()
    94  					var htr map[string]interface{}
    95  					if err = dec.Decode(&htr); err != nil {
    96  						return err
    97  					}
    98  					ht[file.Name] = htr
    99  				}
   100  			}
   101  			b, err := json.MarshalIndent(ht, "", "  ")
   102  			if err != nil {
   103  				return err
   104  			}
   105  			fmt.Println(string(b))
   106  			return nil
   107  		}
   108  		b, err := os.ReadFile(file)
   109  		if err != nil {
   110  			return err
   111  		}
   112  		buf := bytes.NewBuffer(nil)
   113  		if _, err = msgp.CopyToJSON(buf, bytes.NewReader(b)); err != nil {
   114  			return err
   115  		}
   116  		var htr map[string]interface{}
   117  		dec := json.NewDecoder(buf)
   118  		// Use number to preserve integers.
   119  		dec.UseNumber()
   120  		if err = dec.Decode(&htr); err != nil {
   121  			return err
   122  		}
   123  		ht[file] = htr
   124  		b, err = json.MarshalIndent(ht, "", "  ")
   125  		if err != nil {
   126  			return err
   127  		}
   128  		fmt.Println(string(b))
   129  		return nil
   130  	}
   131  
   132  	err := app.Run(os.Args)
   133  	if err != nil {
   134  		log.Fatal(err)
   135  	}
   136  }