From c6fbd58256a2f79e0cc8afc265a224a376d0547f Mon Sep 17 00:00:00 2001 From: Felicitas Pojtinger Date: Tue, 7 Dec 2021 23:01:44 +0100 Subject: [PATCH] refactor: Decompose `delete` func --- cmd/stbak/cmd/delete.go | 158 +++------------------- pkg/config/error.go | 2 + pkg/operations/delete.go | 126 +++++++++++++++++ pkg/operations/{operations.go => move.go} | 11 -- 4 files changed, 145 insertions(+), 152 deletions(-) create mode 100644 pkg/operations/delete.go rename pkg/operations/{operations.go => move.go} (60%) diff --git a/cmd/stbak/cmd/delete.go b/cmd/stbak/cmd/delete.go index bb71ac3..a9264b5 100644 --- a/cmd/stbak/cmd/delete.go +++ b/cmd/stbak/cmd/delete.go @@ -1,20 +1,9 @@ package cmd import ( - "archive/tar" - "context" - - "github.com/pojntfx/stfs/internal/converters" - models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata" - "github.com/pojntfx/stfs/internal/encryption" - "github.com/pojntfx/stfs/internal/formatting" "github.com/pojntfx/stfs/internal/keys" - "github.com/pojntfx/stfs/internal/pax" - "github.com/pojntfx/stfs/internal/persisters" - "github.com/pojntfx/stfs/internal/signature" - "github.com/pojntfx/stfs/internal/tape" "github.com/pojntfx/stfs/pkg/config" - "github.com/pojntfx/stfs/pkg/recovery" + "github.com/pojntfx/stfs/pkg/operations" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/volatiletech/sqlboiler/v4/boil" @@ -68,141 +57,28 @@ var deleteCmd = &cobra.Command{ return err } - return delete( - viper.GetString(driveFlag), + return operations.Delete( + config.StateConfig{ + Drive: viper.GetString(driveFlag), + Metadata: viper.GetString(metadataFlag), + }, + config.PipeConfig{ + Compression: viper.GetString(compressionFlag), + Encryption: viper.GetString(encryptionFlag), + Signature: viper.GetString(signatureFlag), + }, + config.CryptoConfig{ + Recipient: recipient, + Identity: identity, + Password: viper.GetString(passwordFlag), + }, + viper.GetInt(recordSizeFlag), - viper.GetString(metadataFlag), viper.GetString(nameFlag), - viper.GetString(encryptionFlag), - recipient, - viper.GetString(signatureFlag), - identity, ) }, } -func delete( - drive string, - recordSize int, - metadata string, - name string, - encryptionFormat string, - recipient interface{}, - signatureFormat string, - identity interface{}, -) error { - dirty := false - tw, isRegular, cleanup, err := tape.OpenTapeWriteOnly(drive, recordSize, false) - if err != nil { - return err - } - defer cleanup(&dirty) - - metadataPersister := persisters.NewMetadataPersister(metadata) - if err := metadataPersister.Open(); err != nil { - return err - } - - lastIndexedRecord, lastIndexedBlock, err := metadataPersister.GetLastIndexedRecordAndBlock(context.Background(), viper.GetInt(recordSizeFlag)) - if err != nil { - return err - } - - headersToDelete := []*models.Header{} - dbhdr, err := metadataPersister.GetHeader(context.Background(), name) - if err != nil { - return err - } - headersToDelete = append(headersToDelete, dbhdr) - - // If the header refers to a directory, get it's children - if dbhdr.Typeflag == tar.TypeDir { - dbhdrs, err := metadataPersister.GetHeaderChildren(context.Background(), name) - if err != nil { - return err - } - - headersToDelete = append(headersToDelete, dbhdrs...) - } - - if err := formatting.PrintCSV(formatting.TARHeaderCSV); err != nil { - return err - } - - // Append deletion hdrs to the tape or tar file - hdrs := []*tar.Header{} - for _, dbhdr := range headersToDelete { - hdr, err := converters.DBHeaderToTarHeader(dbhdr) - if err != nil { - return err - } - - hdr.Size = 0 // Don't try to seek after the record - hdr.PAXRecords[pax.STFSRecordVersion] = pax.STFSRecordVersion1 - hdr.PAXRecords[pax.STFSRecordAction] = pax.STFSRecordActionDelete - - if err := signature.SignHeader(hdr, isRegular, signatureFormat, identity); err != nil { - return err - } - - if err := encryption.EncryptHeader(hdr, encryptionFormat, recipient); err != nil { - return err - } - - if err := tw.WriteHeader(hdr); err != nil { - return err - } - - dirty = true - - if err := formatting.PrintCSV(formatting.GetTARHeaderAsCSV(-1, -1, -1, -1, hdr)); err != nil { - return err - } - - hdrs = append(hdrs, hdr) - } - - return recovery.Index( - config.StateConfig{ - Drive: viper.GetString(driveFlag), - Metadata: viper.GetString(metadataFlag), - }, - config.PipeConfig{ - Compression: viper.GetString(compressionFlag), - Encryption: viper.GetString(encryptionFlag), - Signature: viper.GetString(signatureFlag), - }, - config.CryptoConfig{ - Recipient: recipient, - Identity: identity, - Password: viper.GetString(passwordFlag), - }, - - viper.GetInt(recordSizeFlag), - int(lastIndexedRecord), - int(lastIndexedBlock), - false, - - func(hdr *tar.Header, i int) error { - // Ignore the first header, which is the last header which we already indexed - if i == 0 { - return nil - } - - if len(hdrs) <= i-1 { - return errMissingTarHeader - } - - *hdr = *hdrs[i-1] - - return nil - }, - func(hdr *tar.Header, isRegular bool) error { - return nil // We sign above, no need to verify - }, - ) -} - func init() { deleteCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record") deleteCmd.PersistentFlags().StringP(nameFlag, "n", "", "Name of the file to remove") diff --git a/pkg/config/error.go b/pkg/config/error.go index 59ba2ef..0c70f80 100644 --- a/pkg/config/error.go +++ b/pkg/config/error.go @@ -21,4 +21,6 @@ var ( ErrCompressionFormatOnlyRegularSupport = errors.New("this compression format only supports regular files, not i.e. tape drives") ErrCompressionFormatRequiresLargerRecordSize = errors.New("this compression format requires a larger record size") ErrCompressionLevelUnsupported = errors.New("compression level is unsupported") + + ErrMissingTarHeader = errors.New("tar header is missing") ) diff --git a/pkg/operations/delete.go b/pkg/operations/delete.go new file mode 100644 index 0000000..1ba40d0 --- /dev/null +++ b/pkg/operations/delete.go @@ -0,0 +1,126 @@ +package operations + +import ( + "archive/tar" + "context" + + "github.com/pojntfx/stfs/internal/converters" + models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata" + "github.com/pojntfx/stfs/internal/encryption" + "github.com/pojntfx/stfs/internal/formatting" + "github.com/pojntfx/stfs/internal/pax" + "github.com/pojntfx/stfs/internal/persisters" + "github.com/pojntfx/stfs/internal/signature" + "github.com/pojntfx/stfs/internal/tape" + "github.com/pojntfx/stfs/pkg/config" + "github.com/pojntfx/stfs/pkg/recovery" +) + +func Delete( + state config.StateConfig, + pipes config.PipeConfig, + crypto config.CryptoConfig, + + recordSize int, + name string, +) error { + dirty := false + tw, isRegular, cleanup, err := tape.OpenTapeWriteOnly(state.Drive, recordSize, false) + if err != nil { + return err + } + defer cleanup(&dirty) + + metadataPersister := persisters.NewMetadataPersister(state.Metadata) + if err := metadataPersister.Open(); err != nil { + return err + } + + lastIndexedRecord, lastIndexedBlock, err := metadataPersister.GetLastIndexedRecordAndBlock(context.Background(), recordSize) + if err != nil { + return err + } + + headersToDelete := []*models.Header{} + dbhdr, err := metadataPersister.GetHeader(context.Background(), name) + if err != nil { + return err + } + headersToDelete = append(headersToDelete, dbhdr) + + // If the header refers to a directory, get it's children + if dbhdr.Typeflag == tar.TypeDir { + dbhdrs, err := metadataPersister.GetHeaderChildren(context.Background(), name) + if err != nil { + return err + } + + headersToDelete = append(headersToDelete, dbhdrs...) + } + + if err := formatting.PrintCSV(formatting.TARHeaderCSV); err != nil { + return err + } + + // Append deletion hdrs to the tape or tar file + hdrs := []*tar.Header{} + for _, dbhdr := range headersToDelete { + hdr, err := converters.DBHeaderToTarHeader(dbhdr) + if err != nil { + return err + } + + hdr.Size = 0 // Don't try to seek after the record + hdr.PAXRecords[pax.STFSRecordVersion] = pax.STFSRecordVersion1 + hdr.PAXRecords[pax.STFSRecordAction] = pax.STFSRecordActionDelete + + if err := signature.SignHeader(hdr, isRegular, pipes.Signature, crypto.Identity); err != nil { + return err + } + + if err := encryption.EncryptHeader(hdr, pipes.Encryption, crypto.Recipient); err != nil { + return err + } + + if err := tw.WriteHeader(hdr); err != nil { + return err + } + + dirty = true + + if err := formatting.PrintCSV(formatting.GetTARHeaderAsCSV(-1, -1, -1, -1, hdr)); err != nil { + return err + } + + hdrs = append(hdrs, hdr) + } + + return recovery.Index( + state, + pipes, + crypto, + + recordSize, + int(lastIndexedRecord), + int(lastIndexedBlock), + false, + + func(hdr *tar.Header, i int) error { + // Ignore the first header, which is the last header which we already indexed + if i == 0 { + return nil + } + + if len(hdrs) <= i-1 { + return config.ErrMissingTarHeader + } + + *hdr = *hdrs[i-1] + + return nil + }, + func(hdr *tar.Header, isRegular bool) error { + return nil // We sign above, no need to verify + }, + ) +} diff --git a/pkg/operations/operations.go b/pkg/operations/move.go similarity index 60% rename from pkg/operations/operations.go rename to pkg/operations/move.go index 981b41c..5661674 100644 --- a/pkg/operations/operations.go +++ b/pkg/operations/move.go @@ -4,17 +4,6 @@ import ( "github.com/pojntfx/stfs/pkg/config" ) -func Delete( - state config.StateConfig, - pipes config.PipeConfig, - crypto config.CryptoConfig, - - recordSize int, - name string, -) error { - return nil -} - func Move( state config.StateConfig, pipes config.PipeConfig,