github.com/cosmos/cosmos-sdk@v0.50.10/client/snapshot/dump.go (about) 1 package snapshot 2 3 import ( 4 "archive/tar" 5 "compress/gzip" 6 "errors" 7 "fmt" 8 "io" 9 "os" 10 "strconv" 11 12 "github.com/spf13/cobra" 13 14 "github.com/cosmos/cosmos-sdk/server" 15 ) 16 17 // DumpArchiveCmd returns a command to dump the snapshot as portable archive format 18 func DumpArchiveCmd() *cobra.Command { 19 cmd := &cobra.Command{ 20 Use: "dump <height> <format>", 21 Short: "Dump the snapshot as portable archive format", 22 Args: cobra.ExactArgs(2), 23 RunE: func(cmd *cobra.Command, args []string) error { 24 ctx := server.GetServerContextFromCmd(cmd) 25 snapshotStore, err := server.GetSnapshotStore(ctx.Viper) 26 if err != nil { 27 return err 28 } 29 30 output, err := cmd.Flags().GetString("output") 31 if err != nil { 32 return err 33 } 34 35 height, err := strconv.ParseUint(args[0], 10, 64) 36 if err != nil { 37 return err 38 } 39 format, err := strconv.ParseUint(args[1], 10, 32) 40 if err != nil { 41 return err 42 } 43 44 if output == "" { 45 output = fmt.Sprintf("%d-%d.tar.gz", height, format) 46 } 47 48 snapshot, err := snapshotStore.Get(height, uint32(format)) 49 if err != nil { 50 return err 51 } 52 53 if snapshot == nil { 54 return errors.New("snapshot doesn't exist") 55 } 56 57 bz, err := snapshot.Marshal() 58 if err != nil { 59 return err 60 } 61 62 fp, err := os.Create(output) 63 if err != nil { 64 return err 65 } 66 defer fp.Close() 67 68 // since the chunk files are already compressed, we just use fastest compression here 69 gzipWriter, err := gzip.NewWriterLevel(fp, gzip.BestSpeed) 70 if err != nil { 71 return err 72 } 73 tarWriter := tar.NewWriter(gzipWriter) 74 if err := tarWriter.WriteHeader(&tar.Header{ 75 Name: SnapshotFileName, 76 Mode: 0o644, 77 Size: int64(len(bz)), 78 }); err != nil { 79 return fmt.Errorf("failed to write snapshot header to tar: %w", err) 80 } 81 if _, err := tarWriter.Write(bz); err != nil { 82 return fmt.Errorf("failed to write snapshot to tar: %w", err) 83 } 84 85 for i := uint32(0); i < snapshot.Chunks; i++ { 86 path := snapshotStore.PathChunk(height, uint32(format), i) 87 file, err := os.Open(path) 88 if err != nil { 89 return fmt.Errorf("failed to open chunk file %s: %w", path, err) 90 } 91 defer file.Close() 92 93 st, err := file.Stat() 94 if err != nil { 95 return fmt.Errorf("failed to stat chunk file %s: %w", path, err) 96 } 97 98 if err := tarWriter.WriteHeader(&tar.Header{ 99 Name: strconv.FormatUint(uint64(i), 10), 100 Mode: 0o644, 101 Size: st.Size(), 102 }); err != nil { 103 return fmt.Errorf("failed to write chunk header to tar: %w", err) 104 } 105 106 if _, err := io.Copy(tarWriter, file); err != nil { 107 return fmt.Errorf("failed to write chunk to tar: %w", err) 108 } 109 } 110 111 if err := tarWriter.Close(); err != nil { 112 return fmt.Errorf("failed to close tar writer: %w", err) 113 } 114 115 if err := gzipWriter.Close(); err != nil { 116 return fmt.Errorf("failed to close gzip writer: %w", err) 117 } 118 119 return fp.Close() 120 }, 121 } 122 123 cmd.Flags().StringP("output", "o", "", "output file") 124 125 return cmd 126 }