keychain: always ensure the default key is generated
Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
a4e31949a3
commit
687c0e33a4
@ -12,6 +12,7 @@ import (
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/input"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/output"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/keychain"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@ -25,8 +26,16 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringP("environment", "e", "", "Select an environment")
|
||||
rootCmd.PersistentFlags().StringP("workspace", "w", "", "Specify a workspace (defaults to current git repository)")
|
||||
|
||||
rootCmd.PersistentPreRun = func(*cobra.Command, []string) {
|
||||
rootCmd.PersistentPreRun = func(cmd *cobra.Command, _ []string) {
|
||||
lg := logger.New()
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
|
||||
go checkVersion()
|
||||
|
||||
err := keychain.EnsureDefaultKey(ctx)
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to generate default key")
|
||||
}
|
||||
}
|
||||
rootCmd.PersistentPostRun = func(*cobra.Command, []string) {
|
||||
warnVersion()
|
||||
|
@ -14,43 +14,65 @@ import (
|
||||
)
|
||||
|
||||
func Path() (string, error) {
|
||||
keysFile, err := homedir.Expand("~/.config/dagger/keys.txt")
|
||||
return homedir.Expand("~/.config/dagger/keys.txt")
|
||||
}
|
||||
|
||||
func EnsureDefaultKey(ctx context.Context) error {
|
||||
keysFile, err := Path()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
// if the keys file doesn't exist, attempt a migration
|
||||
if _, err := os.Stat(keysFile); errors.Is(err, os.ErrNotExist) {
|
||||
migrateKeys(keysFile)
|
||||
// If the keys file already exists, there's nothing to do.
|
||||
_, err = os.Stat(keysFile)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return keysFile, nil
|
||||
// If we got a different error than not existent, abort
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
|
||||
// Attempt a migration from the old keys file
|
||||
migrated, err := migrateKeys(ctx, keysFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we migrated a previous identity, stop here.
|
||||
if migrated {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise, generate a new key
|
||||
log.Ctx(ctx).Debug().Msg("generating default key pair")
|
||||
_, err = Generate(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// migrateKeys attempts a migration from `~/.dagger/keys.txt` to `~/.config/dagger/keys.txt`
|
||||
func migrateKeys(keysFile string) error {
|
||||
func migrateKeys(ctx context.Context, keysFile string) (bool, error) {
|
||||
oldKeysFile, err := homedir.Expand("~/.dagger/keys.txt")
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(oldKeysFile); err != nil {
|
||||
return err
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(keysFile), 0700); err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
return os.Rename(oldKeysFile, keysFile)
|
||||
log.Ctx(ctx).Info().Msg("migrating keychain")
|
||||
return true, os.Rename(oldKeysFile, keysFile)
|
||||
}
|
||||
|
||||
func Default(ctx context.Context) (string, error) {
|
||||
keys, err := List(ctx)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return Generate(ctx)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
@ -85,7 +107,7 @@ func Generate(ctx context.Context) (string, error) {
|
||||
|
||||
pubkey := k.Recipient().String()
|
||||
|
||||
log.Ctx(ctx).Debug().Str("publicKey", pubkey).Msg("generating keypair")
|
||||
log.Ctx(ctx).Debug().Str("publicKey", pubkey).Msg("keypair generated")
|
||||
|
||||
return pubkey, nil
|
||||
}
|
||||
@ -98,7 +120,7 @@ func List(ctx context.Context) ([]*age.X25519Identity, error) {
|
||||
|
||||
f, err := os.Open(keysFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open keys file file %q: %w", keysFile, err)
|
||||
return nil, fmt.Errorf("failed to open keys file %q: %w", keysFile, err)
|
||||
}
|
||||
ids, err := age.ParseIdentities(f)
|
||||
if err != nil {
|
||||
@ -107,7 +129,7 @@ func List(ctx context.Context) ([]*age.X25519Identity, error) {
|
||||
|
||||
keys := make([]*age.X25519Identity, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
key, ok := ids[0].(*age.X25519Identity)
|
||||
key, ok := id.(*age.X25519Identity)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("internal error: unexpected identity type: %T", id)
|
||||
}
|
||||
|
@ -8,12 +8,15 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.dagger.io/dagger/keychain"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestWorkspace(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
|
||||
keychain.EnsureDefaultKey(ctx)
|
||||
|
||||
root, err := os.MkdirTemp(os.TempDir(), "dagger-*")
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -60,6 +63,8 @@ func TestWorkspace(t *testing.T) {
|
||||
func TestEncryption(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
|
||||
keychain.EnsureDefaultKey(ctx)
|
||||
|
||||
readManifest := func(st *State) *State {
|
||||
data, err := os.ReadFile(path.Join(st.Path, manifestFile))
|
||||
require.NoError(t, err)
|
||||
|
Reference in New Issue
Block a user