New 'arca add <device>' subcommand detects a LUKS device via udisks2 and appends it to the config with passphrase as default method. Supports --alias/-a to override the generated name. Skips if UUID already configured. Adds Config.Save() and Config.HasUUID() to config package. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.wntrmute.dev/kyle/arca/internal/config"
|
|
"git.wntrmute.dev/kyle/arca/internal/udisks"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var addAlias string
|
|
|
|
var addCmd = &cobra.Command{
|
|
Use: "add <device>",
|
|
Short: "Add a device to the config",
|
|
Long: "Detects a LUKS device via udisks2 and adds it to the config file with a default passphrase method.",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: runAdd,
|
|
}
|
|
|
|
func init() {
|
|
addCmd.Flags().StringVarP(&addAlias, "alias", "a", "", "alias name (default: first 8 chars of UUID)")
|
|
rootCmd.AddCommand(addCmd)
|
|
}
|
|
|
|
func runAdd(cmd *cobra.Command, args []string) error {
|
|
target := args[0]
|
|
|
|
client, err := udisks.NewClient()
|
|
if err != nil {
|
|
return fmt.Errorf("connecting to udisks2: %w", err)
|
|
}
|
|
defer client.Close()
|
|
|
|
// Find the device to get its UUID.
|
|
dev, err := client.FindDevice("", target)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !dev.HasEncrypted {
|
|
return fmt.Errorf("%s is not a LUKS-encrypted device", target)
|
|
}
|
|
|
|
if dev.UUID == "" {
|
|
return fmt.Errorf("%s has no UUID", target)
|
|
}
|
|
|
|
cfg := config.Load()
|
|
|
|
// Check if already configured.
|
|
if existing := cfg.AliasFor(dev.UUID); existing != "" {
|
|
fmt.Printf("Device %s (UUID %s) already configured as %q\n", dev.DevicePath, dev.UUID, existing)
|
|
return nil
|
|
}
|
|
|
|
alias := addAlias
|
|
if alias == "" {
|
|
alias = aliasFromUUID(dev.UUID)
|
|
}
|
|
|
|
// Check for alias collision.
|
|
if _, exists := cfg.Devices[alias]; exists {
|
|
return fmt.Errorf("alias %q already in use — choose a different name with --alias", alias)
|
|
}
|
|
|
|
cfg.Devices[alias] = config.DeviceConfig{
|
|
UUID: dev.UUID,
|
|
Methods: []string{"passphrase"},
|
|
}
|
|
|
|
if err := cfg.Save(); err != nil {
|
|
return fmt.Errorf("saving config: %w", err)
|
|
}
|
|
|
|
fmt.Printf("Added %s (UUID %s) as %q\n", dev.DevicePath, dev.UUID, alias)
|
|
return nil
|
|
}
|
|
|
|
func aliasFromUUID(uuid string) string {
|
|
clean := strings.ReplaceAll(uuid, "-", "")
|
|
if len(clean) > 8 {
|
|
clean = clean[:8]
|
|
}
|
|
return clean
|
|
}
|