@@ -19,6 +19,7 @@ import (
1919 "github.com/Altinity/clickhouse-backup/v2/pkg/config"
2020 "github.com/Altinity/clickhouse-backup/v2/pkg/storage"
2121 "github.com/antchfx/xmlquery"
22+ "github.com/pkg/errors"
2223 "github.com/puzpuzpuz/xsync"
2324 "github.com/rs/zerolog/log"
2425)
@@ -31,11 +32,13 @@ const (
3132 VersionRelativePath MetadataVersion = 2
3233 VersionReadOnlyFlag MetadataVersion = 3
3334 VersionInlineData MetadataVersion = 4
35+ VersionFullObjectKey MetadataVersion = 5
3436)
3537
3638type StorageObject struct {
37- ObjectSize int64
38- ObjectRelativePath string
39+ IsAbsolute bool
40+ ObjectSize int64
41+ ObjectPath string
3942}
4043
4144type Metadata struct {
@@ -92,7 +95,6 @@ func ReadBoolText(scanner *bufio.Scanner) (bool, error) {
9295
9396func (m * Metadata ) readFromFile (file io.Reader ) error {
9497
95- objectStorageRootPath := ""
9698 scanner := bufio .NewScanner (file )
9799 // todo think about, resize scanner's capacity for lines over 64K
98100 scanner .Split (bufio .ScanWords )
@@ -103,37 +105,44 @@ func (m *Metadata) readFromFile(file io.Reader) error {
103105 return err
104106 }
105107
106- if version < int (VersionAbsolutePaths ) || version > int (VersionInlineData ) {
107- return fmt .Errorf ("invalid metadata.Version=%v" , m . Version )
108+ if version < int (VersionAbsolutePaths ) || version > int (VersionFullObjectKey ) {
109+ return fmt .Errorf ("invalid metadata.Version=%v" , version )
108110 }
109111
110112 m .Version = MetadataVersion (version )
111113
112114 m .StorageObjectCount , err = ReadIntText (scanner )
115+ if err != nil {
116+ return errors .WithStack (errors .Wrap (err , "can't read StorageObjectCount" ))
117+ }
113118
114119 m .TotalSize , err = ReadInt64Text (scanner )
120+ if err != nil {
121+ return errors .WithStack (errors .Wrap (err , "can't read TotalSize" ))
122+ }
115123
116124 for i := 0 ; i < m .StorageObjectCount ; i ++ {
117-
118- objectSize , _ := ReadInt64Text (scanner )
119- scanner .Scan ()
120- objectRelativePath := scanner .Text ()
121-
122- if version == int (VersionAbsolutePaths ) {
123- if ! strings .HasPrefix (objectRelativePath , objectStorageRootPath ) {
124- return fmt .Errorf ("%s doesn't contains %s" , objectRelativePath , objectStorageRootPath )
125- }
126- objectRelativePath = objectRelativePath [len (objectStorageRootPath ):]
125+ storageObject := StorageObject {IsAbsolute : m .Version == VersionAbsolutePaths || m .Version == VersionFullObjectKey }
126+ storageObject .ObjectSize , err = ReadInt64Text (scanner )
127+ if err != nil {
128+ return errors .WithStack (errors .Wrap (err , "can't read ObjectSize" ))
127129 }
128130
129- m .StorageObjects = append (m .StorageObjects , StorageObject {ObjectSize : objectSize , ObjectRelativePath : objectRelativePath })
130-
131+ scanner .Scan ()
132+ storageObject .ObjectPath = scanner .Text ()
133+ m .StorageObjects = append (m .StorageObjects , storageObject )
131134 }
132135
133136 m .RefCount , err = ReadIntText (scanner )
137+ if err != nil {
138+ return errors .WithStack (errors .Wrap (err , "can't read TotalSize" ))
139+ }
134140
135141 if version >= int (VersionReadOnlyFlag ) {
136142 m .ReadOnly , err = ReadBoolText (scanner )
143+ if err != nil {
144+ return errors .WithStack (errors .Wrap (err , "can't read ReadOnly" ))
145+ }
137146 }
138147
139148 if version >= int (VersionInlineData ) {
@@ -156,7 +165,7 @@ func (m *Metadata) writeToFile(file *os.File) error {
156165 }
157166
158167 for i := 0 ; i < m .StorageObjectCount ; i ++ {
159- if _ , err = file .WriteString (strconv .FormatInt (m .StorageObjects [i ].ObjectSize , 10 ) + "\t " + m .StorageObjects [i ].ObjectRelativePath + "\n " ); err != nil {
168+ if _ , err = file .WriteString (strconv .FormatInt (m .StorageObjects [i ].ObjectSize , 10 ) + "\t " + m .StorageObjects [i ].ObjectPath + "\n " ); err != nil {
160169 return err
161170 }
162171 }
@@ -322,6 +331,9 @@ func getObjectDisksCredentials(ctx context.Context, ch *clickhouse.ClickHouse) e
322331 return err
323332 }
324333 root := xmlquery .FindOne (doc , "/" )
334+ if root == nil {
335+ return fmt .Errorf ("object_disk->getObjectDisksCredentials" )
336+ }
325337 disks := xmlquery .Find (doc , fmt .Sprintf ("/%s/storage_configuration/disks/*" , root .Data ))
326338 for _ , d := range disks {
327339 diskName := d .Data
@@ -624,7 +636,7 @@ func ConvertLocalPathToRemote(diskName, localPath string) (string, error) {
624636 if err != nil {
625637 return "" , err
626638 }
627- return meta .StorageObjects [0 ].ObjectRelativePath , nil
639+ return meta .StorageObjects [0 ].ObjectPath , nil
628640}
629641
630642func GetFileReader (ctx context.Context , diskName , remotePath string ) (io.ReadCloser , error ) {
@@ -721,7 +733,10 @@ func GetFileSize(ctx context.Context, ch *clickhouse.ClickHouse, cfg *config.Con
721733*/
722734
723735func CopyObject (ctx context.Context , diskName string , srcSize int64 , srcBucket , srcKey , dstPath string ) (int64 , error ) {
724- connection , _ := DisksConnections .Load (diskName )
736+ connection , ok := DisksConnections .Load (diskName )
737+ if ! ok {
738+ return 0 , errors .WithStack (fmt .Errorf ("can't find %s in object_disk.DiskConnections" , diskName ))
739+ }
725740 remoteStorage := connection .GetRemoteStorage ()
726741 return remoteStorage .CopyObject (ctx , srcSize , srcBucket , srcKey , dstPath )
727742}
0 commit comments