refactor: Decompose all utilities from cmd package
This commit is contained in:
@@ -3,11 +3,9 @@ package cmd
|
||||
import (
|
||||
"archive/tar"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/pojntfx/stfs/internal/compression"
|
||||
"github.com/pojntfx/stfs/internal/keys"
|
||||
"github.com/pojntfx/stfs/internal/persisters"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
@@ -23,29 +21,9 @@ const (
|
||||
fromFlag = "from"
|
||||
overwriteFlag = "overwrite"
|
||||
compressionLevelFlag = "compression-level"
|
||||
|
||||
recipientFlag = "recipient"
|
||||
identityFlag = "identity"
|
||||
passwordFlag = "password"
|
||||
)
|
||||
|
||||
var (
|
||||
knownCompressionLevels = []string{config.CompressionLevelFastest, config.CompressionLevelBalanced, config.CompressionLevelSmallest}
|
||||
|
||||
errUnknownCompressionLevel = errors.New("unknown compression level")
|
||||
errUnsupportedCompressionLevel = errors.New("unsupported compression level")
|
||||
|
||||
errKeyNotAccessible = errors.New("key not found or accessible")
|
||||
|
||||
errMissingTarHeader = errors.New("tar header is missing")
|
||||
|
||||
errRecipientUnparsable = errors.New("recipient could not be parsed")
|
||||
|
||||
errCompressionFormatRequiresLargerRecordSize = errors.New("this compression format requires a larger record size")
|
||||
|
||||
errCompressionFormatOnlyRegularSupport = errors.New("this compression format only supports regular files, not i.e. tape drives")
|
||||
|
||||
errSignatureFormatOnlyRegularSupport = errors.New("this signature format only supports regular files, not i.e. tape drives")
|
||||
recipientFlag = "recipient"
|
||||
identityFlag = "identity"
|
||||
passwordFlag = "password"
|
||||
)
|
||||
|
||||
var archiveCmd = &cobra.Command{
|
||||
@@ -57,15 +35,15 @@ var archiveCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
||||
if err := compression.CheckCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if viper.GetBool(verboseFlag) {
|
||||
@@ -89,7 +67,7 @@ var archiveCmd = &cobra.Command{
|
||||
lastIndexedBlock = b
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -99,7 +77,7 @@ var archiveCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -130,6 +108,9 @@ var archiveCmd = &cobra.Command{
|
||||
viper.GetBool(overwriteFlag),
|
||||
viper.GetString(compressionLevelFlag),
|
||||
)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return recovery.Index(
|
||||
config.StateConfig{
|
||||
@@ -159,7 +140,7 @@ var archiveCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if len(hdrs) <= i-1 {
|
||||
return errMissingTarHeader
|
||||
return config.ErrMissingTarHeader
|
||||
}
|
||||
|
||||
*hdr = *hdrs[i-1]
|
||||
@@ -173,47 +154,11 @@ var archiveCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func checkKeyAccessible(encryptionFormat string, pathToKey string) error {
|
||||
if encryptionFormat == noneKey {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := os.Stat(pathToKey); err != nil {
|
||||
return errKeyNotAccessible
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readKey(encryptionFormat string, pathToKey string) ([]byte, error) {
|
||||
if encryptionFormat == noneKey {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
return ioutil.ReadFile(pathToKey)
|
||||
}
|
||||
|
||||
func checkCompressionLevel(compressionLevel string) error {
|
||||
compressionLevelIsKnown := false
|
||||
|
||||
for _, candidate := range knownCompressionLevels {
|
||||
if compressionLevel == candidate {
|
||||
compressionLevelIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !compressionLevelIsKnown {
|
||||
return errUnknownCompressionLevel
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
archiveCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record")
|
||||
archiveCmd.PersistentFlags().StringP(fromFlag, "f", ".", "File or directory to archive")
|
||||
archiveCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Start writing from the start instead of from the end of the tape or tar file")
|
||||
archiveCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, knownCompressionLevels))
|
||||
archiveCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, config.KnownCompressionLevels))
|
||||
archiveCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for")
|
||||
archiveCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key to sign with")
|
||||
archiveCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")
|
||||
|
||||
@@ -22,22 +22,18 @@ var deleteCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -47,7 +43,7 @@ var deleteCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
)
|
||||
|
||||
var driveEjectCmd = &cobra.Command{
|
||||
@@ -15,10 +14,6 @@ var driveEjectCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
return hardware.Eject(
|
||||
hardware.DriveConfig{
|
||||
Drive: viper.GetString(driveFlag),
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
)
|
||||
|
||||
var driveTellCmd = &cobra.Command{
|
||||
@@ -17,10 +16,6 @@ var driveTellCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
currentRecord, err := hardware.Tell(
|
||||
hardware.DriveConfig{
|
||||
Drive: viper.GetString(driveFlag),
|
||||
|
||||
@@ -9,22 +9,17 @@ import (
|
||||
"github.com/pojntfx/stfs/pkg/utility"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
)
|
||||
|
||||
var keygenCmd = &cobra.Command{
|
||||
Use: "keygen",
|
||||
Aliases: []string{"key", "k"},
|
||||
Short: "Restore a file or directory from tape or tar file",
|
||||
Short: "Generate a encryption or signature key",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, privkey, err := utility.Keygen(
|
||||
config.PipeConfig{
|
||||
Compression: viper.GetString(compressionFlag),
|
||||
|
||||
@@ -18,22 +18,18 @@ var moveCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -43,7 +39,7 @@ var moveCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/pojntfx/stfs/internal/keys"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/pojntfx/stfs/pkg/recovery"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -18,40 +16,22 @@ const (
|
||||
previewFlag = "preview"
|
||||
)
|
||||
|
||||
var (
|
||||
errEmbeddedHeaderMissing = errors.New("embedded header is missing")
|
||||
|
||||
errIdentityUnparsable = errors.New("recipient could not be parsed")
|
||||
|
||||
errInvalidSignature = errors.New("invalid signature")
|
||||
|
||||
errSignatureMissing = errors.New("missing signature")
|
||||
)
|
||||
|
||||
var recoveryFetchCmd = &cobra.Command{
|
||||
Use: "fetch",
|
||||
Short: "Fetch a file or directory from tape or tar file by record and block",
|
||||
Short: "Fetch a file or directory from tape or tar file by record and block without the index",
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -61,7 +41,7 @@ var recoveryFetchCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -72,9 +52,8 @@ var recoveryFetchCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
return recovery.Fetch(
|
||||
config.StateConfig{
|
||||
Drive: viper.GetString(driveFlag),
|
||||
Metadata: viper.GetString(metadataFlag),
|
||||
hardware.DriveConfig{
|
||||
Drive: viper.GetString(driveFlag),
|
||||
},
|
||||
config.PipeConfig{
|
||||
Compression: viper.GetString(compressionFlag),
|
||||
|
||||
@@ -21,22 +21,18 @@ var recoveryIndexCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -46,7 +42,7 @@ var recoveryIndexCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ package cmd
|
||||
import (
|
||||
"github.com/pojntfx/stfs/internal/keys"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/pojntfx/stfs/pkg/recovery"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
)
|
||||
|
||||
var recoveryQueryCmd = &cobra.Command{
|
||||
@@ -17,22 +17,14 @@ var recoveryQueryCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -42,7 +34,7 @@ var recoveryQueryCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -53,9 +45,8 @@ var recoveryQueryCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if _, err := recovery.Query(
|
||||
config.StateConfig{
|
||||
Drive: viper.GetString(driveFlag),
|
||||
Metadata: viper.GetString(metadataFlag),
|
||||
hardware.DriveConfig{
|
||||
Drive: viper.GetString(driveFlag),
|
||||
},
|
||||
config.PipeConfig{
|
||||
Compression: viper.GetString(compressionFlag),
|
||||
|
||||
@@ -22,22 +22,18 @@ var restoreCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if viper.GetBool(verboseFlag) {
|
||||
boil.DebugMode = true
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -47,7 +43,7 @@ var restoreCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,75 +1,26 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pojntfx/stfs/internal/compression"
|
||||
"github.com/pojntfx/stfs/internal/encryption"
|
||||
"github.com/pojntfx/stfs/internal/signature"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
driveFlag = "drive"
|
||||
metadataFlag = "metadata"
|
||||
verboseFlag = "verbose"
|
||||
|
||||
driveFlag = "drive"
|
||||
metadataFlag = "metadata"
|
||||
verboseFlag = "verbose"
|
||||
compressionFlag = "compression"
|
||||
|
||||
noneKey = "none"
|
||||
|
||||
compressionFormatGZipKey = "gzip"
|
||||
compressionFormatGZipSuffix = ".gz"
|
||||
|
||||
compressionFormatParallelGZipKey = "parallelgzip"
|
||||
|
||||
compressionFormatLZ4Key = "lz4"
|
||||
compressionFormatLZ4Suffix = ".lz4"
|
||||
|
||||
compressionFormatZStandardKey = "zstandard"
|
||||
compressionFormatZStandardSuffix = ".zst"
|
||||
|
||||
compressionFormatBrotliKey = "brotli"
|
||||
compressionFormatBrotliSuffix = ".br"
|
||||
|
||||
compressionFormatBzip2Key = "bzip2"
|
||||
compressionFormatBzip2Suffix = ".bz2"
|
||||
|
||||
compressionFormatBzip2ParallelKey = "parallelbzip2"
|
||||
|
||||
encryptionFlag = "encryption"
|
||||
|
||||
encryptionFormatAgeKey = "age"
|
||||
encryptionFormatAgeSuffix = ".age"
|
||||
|
||||
encryptionFormatPGPKey = "pgp"
|
||||
encryptionFormatPGPSuffix = ".pgp"
|
||||
|
||||
signatureFlag = "signature"
|
||||
|
||||
signatureFormatMinisignKey = "minisign"
|
||||
|
||||
signatureFormatPGPKey = "pgp"
|
||||
)
|
||||
|
||||
var (
|
||||
knownCompressionFormats = []string{noneKey, compressionFormatGZipKey, compressionFormatParallelGZipKey, compressionFormatLZ4Key, compressionFormatZStandardKey, compressionFormatBrotliKey, compressionFormatBzip2Key, compressionFormatBzip2ParallelKey}
|
||||
|
||||
errUnknownCompressionFormat = errors.New("unknown compression format")
|
||||
errUnsupportedCompressionFormat = errors.New("unsupported compression format")
|
||||
|
||||
knownEncryptionFormats = []string{noneKey, encryptionFormatAgeKey, encryptionFormatPGPKey}
|
||||
|
||||
errUnknownEncryptionFormat = errors.New("unknown encryption format")
|
||||
errUnsupportedEncryptionFormat = errors.New("unsupported encryption format")
|
||||
errKeygenForFormatUnsupported = errors.New("can not generate keys for this format")
|
||||
|
||||
knownSignatureFormats = []string{noneKey, signatureFormatMinisignKey, signatureFormatPGPKey}
|
||||
|
||||
errUnknownSignatureFormat = errors.New("unknown signature format")
|
||||
errUnsupportedSignatureFormat = errors.New("unsupported signature format")
|
||||
encryptionFlag = "encryption"
|
||||
signatureFlag = "signature"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@@ -83,46 +34,15 @@ https://github.com/pojntfx/stfs`,
|
||||
viper.SetEnvPrefix("stbak")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
|
||||
|
||||
compressionFormatIsKnown := false
|
||||
compressionFormat := viper.GetString(compressionFlag)
|
||||
|
||||
for _, candidate := range knownCompressionFormats {
|
||||
if compressionFormat == candidate {
|
||||
compressionFormatIsKnown = true
|
||||
}
|
||||
if err := compression.CheckCompressionFormat(viper.GetString(compressionFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !compressionFormatIsKnown {
|
||||
return errUnknownCompressionFormat
|
||||
if err := encryption.CheckEncryptionFormat(viper.GetString(encryptionFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encryptionFormatIsKnown := false
|
||||
encryptionFormat := viper.GetString(encryptionFlag)
|
||||
|
||||
for _, candidate := range knownEncryptionFormats {
|
||||
if encryptionFormat == candidate {
|
||||
encryptionFormatIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !encryptionFormatIsKnown {
|
||||
return errUnknownEncryptionFormat
|
||||
}
|
||||
|
||||
signatureFormatIsKnown := false
|
||||
signatureFormat := viper.GetString(signatureFlag)
|
||||
|
||||
for _, candidate := range knownSignatureFormats {
|
||||
if signatureFormat == candidate {
|
||||
signatureFormatIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !signatureFormatIsKnown {
|
||||
return errUnknownSignatureFormat
|
||||
}
|
||||
|
||||
return nil
|
||||
return signature.CheckSignatureFormat(viper.GetString(signatureFlag))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -137,9 +57,9 @@ func Execute() {
|
||||
rootCmd.PersistentFlags().StringP(driveFlag, "d", "/dev/nst0", "Tape or tar file to use")
|
||||
rootCmd.PersistentFlags().StringP(metadataFlag, "m", metadataPath, "Metadata database to use")
|
||||
rootCmd.PersistentFlags().BoolP(verboseFlag, "v", false, "Enable verbose logging")
|
||||
rootCmd.PersistentFlags().StringP(compressionFlag, "c", noneKey, fmt.Sprintf("Compression format to use (default %v, available are %v)", noneKey, knownCompressionFormats))
|
||||
rootCmd.PersistentFlags().StringP(encryptionFlag, "e", noneKey, fmt.Sprintf("Encryption format to use (default %v, available are %v)", noneKey, knownEncryptionFormats))
|
||||
rootCmd.PersistentFlags().StringP(signatureFlag, "s", noneKey, fmt.Sprintf("Signature format to use (default %v, available are %v)", noneKey, knownSignatureFormats))
|
||||
rootCmd.PersistentFlags().StringP(compressionFlag, "c", config.NoneKey, fmt.Sprintf("Compression format to use (default %v, available are %v)", config.NoneKey, config.KnownCompressionFormats))
|
||||
rootCmd.PersistentFlags().StringP(encryptionFlag, "e", config.NoneKey, fmt.Sprintf("Encryption format to use (default %v, available are %v)", config.NoneKey, config.KnownEncryptionFormats))
|
||||
rootCmd.PersistentFlags().StringP(signatureFlag, "s", config.NoneKey, fmt.Sprintf("Signature format to use (default %v, available are %v)", config.NoneKey, config.KnownSignatureFormats))
|
||||
|
||||
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pojntfx/stfs/internal/compression"
|
||||
"github.com/pojntfx/stfs/internal/keys"
|
||||
"github.com/pojntfx/stfs/internal/persisters"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
@@ -24,15 +25,15 @@ var updateCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
||||
if err := compression.CheckCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||
@@ -53,7 +54,7 @@ var updateCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -63,7 +64,7 @@ var updateCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -126,7 +127,7 @@ var updateCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if len(hdrs) <= i-1 {
|
||||
return errMissingTarHeader
|
||||
return config.ErrMissingTarHeader
|
||||
}
|
||||
|
||||
*hdr = *hdrs[i-1]
|
||||
@@ -144,7 +145,7 @@ func init() {
|
||||
updateCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record")
|
||||
updateCmd.PersistentFlags().StringP(fromFlag, "f", "", "Path of the file or directory to update")
|
||||
updateCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Replace the content on the tape or tar file")
|
||||
updateCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, knownCompressionLevels))
|
||||
updateCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, config.KnownCompressionLevels))
|
||||
updateCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for")
|
||||
updateCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key to sign with")
|
||||
updateCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")
|
||||
|
||||
37
internal/compression/check.go
Normal file
37
internal/compression/check.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package compression
|
||||
|
||||
import (
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
)
|
||||
|
||||
func CheckCompressionFormat(compressionFormat string) error {
|
||||
compressionFormatIsKnown := false
|
||||
|
||||
for _, candidate := range config.KnownCompressionFormats {
|
||||
if compressionFormat == candidate {
|
||||
compressionFormatIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !compressionFormatIsKnown {
|
||||
return config.ErrCompressionFormatUnknown
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckCompressionLevel(compressionLevel string) error {
|
||||
compressionLevelIsKnown := false
|
||||
|
||||
for _, candidate := range config.KnownCompressionLevels {
|
||||
if compressionLevel == candidate {
|
||||
compressionLevelIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !compressionLevelIsKnown {
|
||||
return config.ErrCompressionLevelUnknown
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
19
internal/encryption/check.go
Normal file
19
internal/encryption/check.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package encryption
|
||||
|
||||
import "github.com/pojntfx/stfs/pkg/config"
|
||||
|
||||
func CheckEncryptionFormat(encryptionFormat string) error {
|
||||
encryptionFormatIsKnown := false
|
||||
|
||||
for _, candidate := range config.KnownEncryptionFormats {
|
||||
if encryptionFormat == candidate {
|
||||
encryptionFormatIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !encryptionFormatIsKnown {
|
||||
return config.ErrEncryptionFormatUnknown
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
"io"
|
||||
|
||||
"filippo.io/age"
|
||||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
"github.com/pojntfx/stfs/internal/noop"
|
||||
"github.com/pojntfx/stfs/internal/pax"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
)
|
||||
|
||||
func Encrypt(
|
||||
|
||||
24
internal/keys/check.go
Normal file
24
internal/keys/check.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrKeyNotAccessible = errors.New("key not found or accessible")
|
||||
)
|
||||
|
||||
func CheckKeyAccessible(encryptionFormat string, pathToKey string) error {
|
||||
if encryptionFormat == config.NoneKey {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := os.Stat(pathToKey); err != nil {
|
||||
return ErrKeyNotAccessible
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
15
internal/keys/read.go
Normal file
15
internal/keys/read.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
)
|
||||
|
||||
func ReadKey(encryptionFormat string, pathToKey string) ([]byte, error) {
|
||||
if encryptionFormat == config.NoneKey {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
return ioutil.ReadFile(pathToKey)
|
||||
}
|
||||
19
internal/signature/check.go
Normal file
19
internal/signature/check.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package signature
|
||||
|
||||
import "github.com/pojntfx/stfs/pkg/config"
|
||||
|
||||
func CheckSignatureFormat(signatureFormat string) error {
|
||||
signatureFormatIsKnown := false
|
||||
|
||||
for _, candidate := range config.KnownSignatureFormats {
|
||||
if signatureFormat == candidate {
|
||||
signatureFormatIsKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if !signatureFormatIsKnown {
|
||||
return config.ErrSignatureFormatUnknown
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -21,3 +21,13 @@ const (
|
||||
CompressionLevelBalanced = "balanced"
|
||||
CompressionLevelSmallest = "smallest"
|
||||
)
|
||||
|
||||
var (
|
||||
KnownCompressionLevels = []string{CompressionLevelFastest, CompressionLevelBalanced, CompressionLevelSmallest}
|
||||
|
||||
KnownCompressionFormats = []string{NoneKey, CompressionFormatGZipKey, CompressionFormatParallelGZipKey, CompressionFormatLZ4Key, CompressionFormatZStandardKey, CompressionFormatBrotliKey, CompressionFormatBzip2Key, CompressionFormatBzip2ParallelKey}
|
||||
|
||||
KnownEncryptionFormats = []string{NoneKey, EncryptionFormatAgeKey, EncryptionFormatPGPKey}
|
||||
|
||||
KnownSignatureFormats = []string{NoneKey, SignatureFormatMinisignKey, SignatureFormatPGPKey}
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package config
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrEncryptionFormatUnknown = errors.New("unknown encryption format")
|
||||
ErrEncryptionFormatUnsupported = errors.New("unsupported encryption format")
|
||||
|
||||
ErrIdentityUnparsable = errors.New("recipient could not be parsed")
|
||||
@@ -10,6 +11,7 @@ var (
|
||||
|
||||
ErrEmbeddedHeaderMissing = errors.New("embedded header is missing")
|
||||
|
||||
ErrSignatureFormatUnknown = errors.New("unknown signature format")
|
||||
ErrSignatureFormatUnsupported = errors.New("unsupported signature format")
|
||||
ErrSignatureFormatOnlyRegularSupport = errors.New("this signature format only supports regular files, not i.e. tape drives")
|
||||
ErrSignatureInvalid = errors.New("signature is invalid")
|
||||
@@ -17,10 +19,12 @@ var (
|
||||
|
||||
ErrKeygenForFormatUnsupported = errors.New("can not generate keys for this format")
|
||||
|
||||
ErrCompressionFormatUnknown = errors.New("unknown compression format")
|
||||
ErrCompressionFormatUnsupported = errors.New("unsupported compression format")
|
||||
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")
|
||||
ErrCompressionLevelUnknown = errors.New("unknown compression level")
|
||||
|
||||
ErrMissingTarHeader = errors.New("tar header is missing")
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/pojntfx/stfs/internal/formatting"
|
||||
"github.com/pojntfx/stfs/internal/persisters"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/pojntfx/stfs/pkg/recovery"
|
||||
)
|
||||
|
||||
@@ -88,7 +89,9 @@ func Restore(
|
||||
}
|
||||
|
||||
if err := recovery.Fetch(
|
||||
state,
|
||||
hardware.DriveConfig{
|
||||
Drive: state.Drive,
|
||||
},
|
||||
pipes,
|
||||
crypto,
|
||||
|
||||
|
||||
@@ -15,10 +15,11 @@ import (
|
||||
"github.com/pojntfx/stfs/internal/signature"
|
||||
"github.com/pojntfx/stfs/internal/tape"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
)
|
||||
|
||||
func Fetch(
|
||||
state config.StateConfig,
|
||||
state hardware.DriveConfig,
|
||||
pipes config.PipeConfig,
|
||||
crypto config.CryptoConfig,
|
||||
|
||||
|
||||
@@ -14,10 +14,11 @@ import (
|
||||
"github.com/pojntfx/stfs/internal/signature"
|
||||
"github.com/pojntfx/stfs/internal/tape"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
)
|
||||
|
||||
func Query(
|
||||
state config.StateConfig,
|
||||
state hardware.DriveConfig,
|
||||
pipes config.PipeConfig,
|
||||
crypto config.CryptoConfig,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user