mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-11-10 12:30:41 +00:00
4be471c196
* feat(lambda): deliver guest configuration on a disk the agent erases * feat(lambda): boot test-link attempts under Firecracker with a kernel hard kill * fix(lambda): detect the configuration disk by its missing fw_cfg entry * test(lambda): cover the configuration-disk seal from the agent and state in-package reasons * fix(lambda): release a Firecracker attempt whose supervisor never started
64 lines
1.8 KiB
Go
64 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
lambdav1 "github.com/mulgadc/spinifex/contracts/lambda/v1"
|
|
"github.com/mulgadc/spinifex/spinifex/agents/lambda/hostlink"
|
|
)
|
|
|
|
// Exit statuses: the guest refused to start, the control connection failed,
|
|
// or the host closed it.
|
|
const (
|
|
exitRefused = 2
|
|
exitLink = 1
|
|
exitClosed = 0
|
|
)
|
|
|
|
type startup struct {
|
|
fwCfgDir string
|
|
fwCfgRoot string
|
|
unload func() error
|
|
}
|
|
|
|
func defaultStartup() startup {
|
|
if _, err := os.Stat(hostlink.ConfigDiskRoot); err == nil {
|
|
return configDiskStartup(hostlink.ConfigDiskRoot, hostlink.ConfigDiskDevice)
|
|
}
|
|
return startup{fwCfgDir: hostlink.FwCfgDir, fwCfgRoot: hostlink.FwCfgRoot, unload: hostlink.UnloadFwCfg}
|
|
}
|
|
|
|
// configDiskStartup reads the entries init extracted from the configuration
|
|
// disk, and seals by erasing the disk and removing the extracted tree.
|
|
func configDiskStartup(root, device string) startup {
|
|
return startup{
|
|
fwCfgDir: root + "/by_name/" + lambdav1.FwCfgPrefix,
|
|
fwCfgRoot: root,
|
|
unload: func() error { return hostlink.SealConfigDisk(device, root) },
|
|
}
|
|
}
|
|
|
|
// connect loads the identity, seals fw_cfg whether or not the load succeeded,
|
|
// then dials the host. Under TLS 1.3 a host refusal is seen only on first read.
|
|
func (s startup) connect(ctx context.Context) (*tls.Conn, lambdav1.Scope, int, error) {
|
|
id, loadErr := hostlink.LoadIdentity(s.fwCfgDir)
|
|
if err := hostlink.SealFwCfg(s.fwCfgRoot, s.unload); err != nil {
|
|
return nil, "", exitRefused, errors.Join(loadErr, err)
|
|
}
|
|
if loadErr != nil {
|
|
return nil, "", exitRefused, loadErr
|
|
}
|
|
conn, err := hostlink.Dial(ctx, id)
|
|
if err != nil {
|
|
if ctx.Err() != nil {
|
|
err = fmt.Errorf("%w: %w", err, context.Cause(ctx))
|
|
}
|
|
return nil, "", exitLink, err
|
|
}
|
|
return conn, id.Scope, 0, nil
|
|
}
|