mirror of
https://github.com/getcompanion-ai/computer-host.git
synced 2026-04-15 03:00:42 +00:00
chore: zsh prompt alignment
This commit is contained in:
parent
3eb610b703
commit
39f8882c30
8 changed files with 56 additions and 11 deletions
|
|
@ -41,7 +41,7 @@ type Daemon struct {
|
|||
store store.Store
|
||||
runtime Runtime
|
||||
|
||||
reconfigureGuestIdentity func(context.Context, string, contracthost.MachineID) error
|
||||
reconfigureGuestIdentity func(context.Context, string, contracthost.MachineID, *contracthost.GuestConfig) error
|
||||
readGuestSSHPublicKey func(context.Context, string) (string, error)
|
||||
syncGuestFilesystem func(context.Context, string) error
|
||||
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ func TestCreateMachineStagesArtifactsAndPersistsState(t *testing.T) {
|
|||
RootFSURL: server.URL + "/rootfs",
|
||||
},
|
||||
GuestConfig: &contracthost.GuestConfig{
|
||||
Hostname: "workbox",
|
||||
AuthorizedKeys: []string{
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAITestOverrideKey daemon-test",
|
||||
},
|
||||
|
|
@ -179,7 +180,7 @@ func TestCreateMachineStagesArtifactsAndPersistsState(t *testing.T) {
|
|||
if !ok {
|
||||
t.Fatalf("mmds payload type mismatch: got %T", runtime.lastSpec.MMDS.Data)
|
||||
}
|
||||
if payload.Latest.MetaData.Hostname != "vm-1" {
|
||||
if payload.Latest.MetaData.Hostname != "workbox" {
|
||||
t.Fatalf("mmds hostname mismatch: got %q", payload.Latest.MetaData.Hostname)
|
||||
}
|
||||
authorizedKeys := strings.Join(payload.Latest.MetaData.AuthorizedKeys, "\n")
|
||||
|
|
@ -340,7 +341,7 @@ func TestRestoreSnapshotFallsBackToLocalSnapshotNetwork(t *testing.T) {
|
|||
t.Fatalf("create daemon: %v", err)
|
||||
}
|
||||
stubGuestSSHPublicKeyReader(hostDaemon)
|
||||
hostDaemon.reconfigureGuestIdentity = func(context.Context, string, contracthost.MachineID) error { return nil }
|
||||
hostDaemon.reconfigureGuestIdentity = func(context.Context, string, contracthost.MachineID, *contracthost.GuestConfig) error { return nil }
|
||||
|
||||
artifactRef := contracthost.ArtifactRef{KernelImageURL: "kernel", RootFSURL: "rootfs"}
|
||||
kernelPath := filepath.Join(root, "artifact-kernel")
|
||||
|
|
@ -397,6 +398,7 @@ func TestRestoreSnapshotFallsBackToLocalSnapshotNetwork(t *testing.T) {
|
|||
{ID: "disk-system", Kind: contracthost.SnapshotArtifactKindDisk, Name: "system.img", DownloadURL: server.URL + "/system"},
|
||||
},
|
||||
},
|
||||
GuestConfig: &contracthost.GuestConfig{Hostname: "restored-shell"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("restore snapshot: %v", err)
|
||||
|
|
@ -462,9 +464,11 @@ func TestRestoreSnapshotUsesDurableSnapshotSpec(t *testing.T) {
|
|||
stubGuestSSHPublicKeyReader(hostDaemon)
|
||||
var reconfiguredHost string
|
||||
var reconfiguredMachine contracthost.MachineID
|
||||
hostDaemon.reconfigureGuestIdentity = func(_ context.Context, host string, machineID contracthost.MachineID) error {
|
||||
var reconfiguredConfig *contracthost.GuestConfig
|
||||
hostDaemon.reconfigureGuestIdentity = func(_ context.Context, host string, machineID contracthost.MachineID, guestConfig *contracthost.GuestConfig) error {
|
||||
reconfiguredHost = host
|
||||
reconfiguredMachine = machineID
|
||||
reconfiguredConfig = cloneGuestConfig(guestConfig)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -497,6 +501,7 @@ func TestRestoreSnapshotUsesDurableSnapshotSpec(t *testing.T) {
|
|||
{ID: "disk-user-0", Kind: contracthost.SnapshotArtifactKindDisk, Name: "user-0.img", DownloadURL: server.URL + "/user-0"},
|
||||
},
|
||||
},
|
||||
GuestConfig: &contracthost.GuestConfig{Hostname: "restored-shell"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("restore snapshot: %v", err)
|
||||
|
|
@ -525,6 +530,9 @@ func TestRestoreSnapshotUsesDurableSnapshotSpec(t *testing.T) {
|
|||
if reconfiguredHost != "127.0.0.1" || reconfiguredMachine != "restored" {
|
||||
t.Fatalf("guest identity reconfigure mismatch: host=%q machine=%q", reconfiguredHost, reconfiguredMachine)
|
||||
}
|
||||
if reconfiguredConfig == nil || reconfiguredConfig.Hostname != "restored-shell" {
|
||||
t.Fatalf("guest identity hostname mismatch: %#v", reconfiguredConfig)
|
||||
}
|
||||
|
||||
machine, err := fileStore.GetMachine(context.Background(), "restored")
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -251,9 +251,13 @@ func (d *Daemon) mergedGuestConfig(config *contracthost.GuestConfig) (*contracth
|
|||
}
|
||||
|
||||
merged := &contracthost.GuestConfig{
|
||||
Hostname: "",
|
||||
AuthorizedKeys: authorizedKeys,
|
||||
TrustedUserCAKeys: nil,
|
||||
}
|
||||
if config != nil {
|
||||
merged.Hostname = strings.TrimSpace(config.Hostname)
|
||||
}
|
||||
if strings.TrimSpace(d.config.GuestLoginCAPublicKey) != "" {
|
||||
merged.TrustedUserCAKeys = append(merged.TrustedUserCAKeys, d.config.GuestLoginCAPublicKey)
|
||||
}
|
||||
|
|
@ -447,6 +451,21 @@ func validateGuestConfig(config *contracthost.GuestConfig) error {
|
|||
if config == nil {
|
||||
return nil
|
||||
}
|
||||
if config.Hostname != "" {
|
||||
hostname := strings.TrimSpace(config.Hostname)
|
||||
if hostname == "" {
|
||||
return fmt.Errorf("guest_config.hostname is required")
|
||||
}
|
||||
if len(hostname) > 63 {
|
||||
return fmt.Errorf("guest_config.hostname must be 63 characters or fewer")
|
||||
}
|
||||
if strings.ContainsAny(hostname, "/\\") {
|
||||
return fmt.Errorf("guest_config.hostname must not contain path separators")
|
||||
}
|
||||
if strings.ContainsAny(hostname, " \t\r\n") {
|
||||
return fmt.Errorf("guest_config.hostname must not contain whitespace")
|
||||
}
|
||||
}
|
||||
for i, key := range config.AuthorizedKeys {
|
||||
if strings.TrimSpace(key) == "" {
|
||||
return fmt.Errorf("guest_config.authorized_keys[%d] is required", i)
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ import (
|
|||
contracthost "github.com/getcompanion-ai/computer-host/contract"
|
||||
)
|
||||
|
||||
func (d *Daemon) reconfigureGuestIdentityOverSSH(ctx context.Context, runtimeHost string, machineID contracthost.MachineID) error {
|
||||
func (d *Daemon) reconfigureGuestIdentityOverSSH(ctx context.Context, runtimeHost string, machineID contracthost.MachineID, guestConfig *contracthost.GuestConfig) error {
|
||||
runtimeHost = strings.TrimSpace(runtimeHost)
|
||||
machineName := strings.TrimSpace(string(machineID))
|
||||
machineName := guestHostname(machineID, guestConfig)
|
||||
if runtimeHost == "" {
|
||||
return fmt.Errorf("guest runtime host is required")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ func cloneGuestConfig(config *contracthost.GuestConfig) *contracthost.GuestConfi
|
|||
return nil
|
||||
}
|
||||
cloned := &contracthost.GuestConfig{
|
||||
Hostname: config.Hostname,
|
||||
AuthorizedKeys: append([]string(nil), config.AuthorizedKeys...),
|
||||
TrustedUserCAKeys: append([]string(nil), config.TrustedUserCAKeys...),
|
||||
}
|
||||
|
|
@ -45,8 +46,17 @@ func cloneGuestConfig(config *contracthost.GuestConfig) *contracthost.GuestConfi
|
|||
return cloned
|
||||
}
|
||||
|
||||
func guestHostname(machineID contracthost.MachineID, guestConfig *contracthost.GuestConfig) string {
|
||||
if guestConfig != nil {
|
||||
if hostname := strings.TrimSpace(guestConfig.Hostname); hostname != "" {
|
||||
return hostname
|
||||
}
|
||||
}
|
||||
return strings.TrimSpace(string(machineID))
|
||||
}
|
||||
|
||||
func (d *Daemon) guestMetadataSpec(machineID contracthost.MachineID, guestConfig *contracthost.GuestConfig) (*firecracker.MMDSSpec, error) {
|
||||
name := strings.TrimSpace(string(machineID))
|
||||
name := guestHostname(machineID, guestConfig)
|
||||
if name == "" {
|
||||
return nil, fmt.Errorf("machine id is required")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ func TestRestoreSnapshotDeletesSystemVolumeRecordWhenRelayAllocationFails(t *tes
|
|||
t.Fatalf("create daemon: %v", err)
|
||||
}
|
||||
stubGuestSSHPublicKeyReader(hostDaemon)
|
||||
hostDaemon.reconfigureGuestIdentity = func(context.Context, string, contracthost.MachineID) error { return nil }
|
||||
hostDaemon.reconfigureGuestIdentity = func(context.Context, string, contracthost.MachineID, *contracthost.GuestConfig) error { return nil }
|
||||
|
||||
artifactRef := contracthost.ArtifactRef{KernelImageURL: "kernel", RootFSURL: "rootfs"}
|
||||
kernelPath := filepath.Join(root, "artifact-kernel")
|
||||
|
|
@ -695,7 +695,7 @@ func TestRestoreSnapshotCleansStagingArtifactsAfterSuccess(t *testing.T) {
|
|||
t.Fatalf("create daemon: %v", err)
|
||||
}
|
||||
stubGuestSSHPublicKeyReader(hostDaemon)
|
||||
hostDaemon.reconfigureGuestIdentity = func(context.Context, string, contracthost.MachineID) error { return nil }
|
||||
hostDaemon.reconfigureGuestIdentity = func(context.Context, string, contracthost.MachineID, *contracthost.GuestConfig) error { return nil }
|
||||
|
||||
server := newRestoreArtifactServer(t, map[string][]byte{
|
||||
"/kernel": []byte("kernel"),
|
||||
|
|
|
|||
|
|
@ -222,6 +222,13 @@ func (d *Daemon) RestoreSnapshot(ctx context.Context, snapshotID contracthost.Sn
|
|||
if err := validateArtifactRef(req.Artifact); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateGuestConfig(req.GuestConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
guestConfig, err := d.mergedGuestConfig(req.GuestConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unlock := d.lockMachine(req.MachineID)
|
||||
defer unlock()
|
||||
|
|
@ -349,7 +356,7 @@ func (d *Daemon) RestoreSnapshot(ctx context.Context, snapshotID contracthost.Sn
|
|||
clearOperation = true
|
||||
return nil, fmt.Errorf("wait for restored guest ready: %w", err)
|
||||
}
|
||||
if err := d.reconfigureGuestIdentity(ctx, machineState.RuntimeHost, req.MachineID); err != nil {
|
||||
if err := d.reconfigureGuestIdentity(ctx, machineState.RuntimeHost, req.MachineID, guestConfig); err != nil {
|
||||
_ = d.runtime.Delete(ctx, *machineState)
|
||||
_ = os.RemoveAll(filepath.Dir(newSystemDiskPath))
|
||||
clearOperation = true
|
||||
|
|
@ -406,6 +413,7 @@ func (d *Daemon) RestoreSnapshot(ctx context.Context, snapshotID contracthost.Sn
|
|||
machineRecord := model.MachineRecord{
|
||||
ID: req.MachineID,
|
||||
Artifact: req.Artifact,
|
||||
GuestConfig: cloneGuestConfig(guestConfig),
|
||||
SystemVolumeID: systemVolumeID,
|
||||
UserVolumeIDs: restoredUserVolumeIDs,
|
||||
RuntimeHost: machineState.RuntimeHost,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue