mirror of
https://github.com/lima-vm/lima.git
synced 2026-10-28 11:44:35 +08:00
refactor: pass through all context to avoid context.TODO() use
Signed-off-by: zyfy29 <wasuremono127@gmail.com>
This commit is contained in:
1 parent
e52cd77b83
commit
aa5a42cf71
82 files changed
+397
-380
No files matched your search
@@ -4,11 +4,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lima-vm/lima/v2/pkg/driver/external/server"
|
||||
"github.com/lima-vm/lima/v2/pkg/driver/qemu"
|
||||
)
|
||||
|
||||
// To be used as an external driver for Lima.
|
||||
func main() {
|
||||
server.Serve(qemu.New())
|
||||
server.Serve(context.Background(), qemu.New())
|
||||
}
|
||||
@@ -4,11 +4,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lima-vm/lima/v2/pkg/driver/external/server"
|
||||
"github.com/lima-vm/lima/v2/pkg/driver/vz"
|
||||
)
|
||||
|
||||
// To be used as an external driver for Lima.
|
||||
func main() {
|
||||
server.Serve(vz.New())
|
||||
server.Serve(context.Background(), vz.New())
|
||||
}
|
||||
@@ -4,11 +4,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lima-vm/lima/v2/pkg/driver/external/server"
|
||||
"github.com/lima-vm/lima/v2/pkg/driver/wsl2"
|
||||
)
|
||||
|
||||
// To be used as an external driver for Lima.
|
||||
func main() {
|
||||
server.Serve(wsl2.New())
|
||||
server.Serve(context.Background(), wsl2.New())
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func daemonAction(cmd *cobra.Command, _ []string) error {
|
||||
return ticker.C, ticker.Stop
|
||||
}
|
||||
|
||||
agent, err := guestagent.New(newTicker, tick*20)
|
||||
agent, err := guestagent.New(ctx, newTicker, tick*20)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func cloneAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
oldInstName, newInstName := args[0], args[1]
|
||||
oldInst, err := store.Inspect(oldInstName)
|
||||
oldInst, err := store.Inspect(ctx, oldInstName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("instance %q not found", oldInstName)
|
||||
@@ -75,20 +75,20 @@ func cloneAction(cmd *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
y, err := limayaml.LoadWithWarnings(yBytes, filePath)
|
||||
y, err := limayaml.LoadWithWarnings(ctx, yBytes, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := limayaml.Validate(y, true); err != nil {
|
||||
return saveRejectedYAML(yBytes, err)
|
||||
}
|
||||
if err := limayaml.ValidateAgainstLatestConfig(yBytes, yContent); err != nil {
|
||||
if err := limayaml.ValidateAgainstLatestConfig(ctx, yBytes, yContent); err != nil {
|
||||
return saveRejectedYAML(yBytes, err)
|
||||
}
|
||||
if err := os.WriteFile(filePath, yBytes, 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
newInst, err = store.Inspect(newInst.Name)
|
||||
newInst, err = store.Inspect(ctx, newInst.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+5
-5
@@ -89,11 +89,11 @@ func copyAction(cmd *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
legacySSH := sshutil.DetectOpenSSHVersion(sshExe).LessThan(*semver.New("8.0.0"))
|
||||
legacySSH := sshutil.DetectOpenSSHVersion(ctx, sshExe).LessThan(*semver.New("8.0.0"))
|
||||
for _, arg := range args {
|
||||
if runtime.GOOS == "windows" {
|
||||
if filepath.IsAbs(arg) {
|
||||
arg, err = ioutilx.WindowsSubsystemPath(arg)
|
||||
arg, err = ioutilx.WindowsSubsystemPath(ctx, arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func copyAction(cmd *cobra.Command, args []string) error {
|
||||
scpArgs = append(scpArgs, arg)
|
||||
case 2:
|
||||
instName := path[0]
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName)
|
||||
@@ -144,7 +144,7 @@ func copyAction(cmd *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sshOpts, err = sshutil.SSHOpts(sshExe, inst.Dir, *inst.Config.User.Name, false, false, false, false)
|
||||
sshOpts, err = sshutil.SSHOpts(ctx, sshExe, inst.Dir, *inst.Config.User.Name, false, false, false, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -155,7 +155,7 @@ func copyAction(cmd *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sshOpts, err = sshutil.CommonOpts(sshExe, false)
|
||||
sshOpts, err = sshutil.CommonOpts(ctx, sshExe, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -33,12 +33,13 @@ func newDeleteCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func deleteAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
force, err := cmd.Flags().GetBool("force")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, instName := range args {
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
logrus.Warnf("Ignoring non-existent instance %q", instName)
|
||||
@@ -50,7 +51,7 @@ func deleteAction(cmd *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("failed to delete instance %q: %w", instName, err)
|
||||
}
|
||||
if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
|
||||
deleted, err := autostart.DeleteStartAtLoginEntry(runtime.GOOS, instName)
|
||||
deleted, err := autostart.DeleteStartAtLoginEntry(ctx, runtime.GOOS, instName)
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
logrus.WithError(err).Warnf("The autostart file for instance %q does not exist", instName)
|
||||
} else if deleted {
|
||||
|
||||
+12
-8
@@ -71,6 +71,7 @@ $ limactl disk create DISK --size SIZE [--format qcow2]
|
||||
}
|
||||
|
||||
func diskCreateAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
size, err := cmd.Flags().GetString("size")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -112,8 +113,8 @@ func diskCreateAction(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// qemu may not be available, use it only if needed.
|
||||
dataDisk := filepath.Join(diskDir, filenames.DataDisk)
|
||||
diskUtil := proxyimgutil.NewDiskUtil()
|
||||
err = diskUtil.CreateDisk(dataDisk, diskSize)
|
||||
diskUtil := proxyimgutil.NewDiskUtil(ctx)
|
||||
err = diskUtil.CreateDisk(ctx, dataDisk, diskSize)
|
||||
if err != nil {
|
||||
rerr := os.RemoveAll(diskDir)
|
||||
if rerr != nil {
|
||||
@@ -232,6 +233,7 @@ $ limactl disk delete DISK1 DISK2 ...
|
||||
}
|
||||
|
||||
func diskDeleteAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
force, err := cmd.Flags().GetBool("force")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -243,7 +245,7 @@ func diskDeleteAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
var instances []*store.Instance
|
||||
for _, instName := range instNames {
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -319,7 +321,8 @@ $ limactl disk unlock DISK1 DISK2 ...
|
||||
return diskUnlockCommand
|
||||
}
|
||||
|
||||
func diskUnlockAction(_ *cobra.Command, args []string) error {
|
||||
func diskUnlockAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
for _, diskName := range args {
|
||||
disk, err := store.InspectDisk(diskName)
|
||||
if err != nil {
|
||||
@@ -334,7 +337,7 @@ func diskUnlockAction(_ *cobra.Command, args []string) error {
|
||||
continue
|
||||
}
|
||||
// if store.Inspect throws an error, the instance does not exist, and it is safe to unlock
|
||||
inst, err := store.Inspect(disk.Instance)
|
||||
inst, err := store.Inspect(ctx, disk.Instance)
|
||||
if err == nil {
|
||||
if len(inst.Errors) > 0 {
|
||||
logrus.Warnf("Cannot unlock disk %q, attached instance %q has errors: %+v",
|
||||
@@ -371,6 +374,7 @@ $ limactl disk resize DISK --size SIZE`,
|
||||
}
|
||||
|
||||
func diskResizeAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
size, err := cmd.Flags().GetString("size")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -396,7 +400,7 @@ func diskResizeAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if disk.Instance != "" {
|
||||
inst, err := store.Inspect(disk.Instance)
|
||||
inst, err := store.Inspect(ctx, disk.Instance)
|
||||
if err == nil {
|
||||
if inst.Status == store.StatusRunning {
|
||||
return fmt.Errorf("cannot resize disk %q used by running instance %q. Please stop the VM instance", diskName, disk.Instance)
|
||||
@@ -406,8 +410,8 @@ func diskResizeAction(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// qemu may not be available, use it only if needed.
|
||||
dataDisk := filepath.Join(disk.Dir, filenames.DataDisk)
|
||||
diskUtil := proxyimgutil.NewDiskUtil()
|
||||
err = diskUtil.ResizeDisk(dataDisk, diskSize)
|
||||
diskUtil := proxyimgutil.NewDiskUtil(ctx)
|
||||
err = diskUtil.ResizeDisk(ctx, dataDisk, diskSize)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resize disk %q: %w", diskName, err)
|
||||
}
|
||||
|
||||
+6
-6
@@ -38,6 +38,7 @@ func newEditCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func editAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
var arg string
|
||||
if len(args) > 0 {
|
||||
arg = args[0]
|
||||
@@ -51,7 +52,7 @@ func editAction(cmd *cobra.Command, args []string) error {
|
||||
arg = DefaultInstanceName
|
||||
}
|
||||
if err := store.ValidateInstName(arg); err == nil {
|
||||
inst, err = store.Inspect(arg)
|
||||
inst, err = store.Inspect(ctx, arg)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("instance %q not found", arg)
|
||||
@@ -100,7 +101,7 @@ func editAction(cmd *cobra.Command, args []string) error {
|
||||
hdr += "# and an empty file will abort the edit.\n"
|
||||
hdr += "\n"
|
||||
hdr += editutil.GenerateEditorWarningHeader()
|
||||
yBytes, err = editutil.OpenEditor(yContent, hdr)
|
||||
yBytes, err = editutil.OpenEditor(ctx, yContent, hdr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -113,7 +114,7 @@ func editAction(cmd *cobra.Command, args []string) error {
|
||||
logrus.Info("Aborting, no changes made to the instance")
|
||||
return nil
|
||||
}
|
||||
y, err := limayaml.LoadWithWarnings(yBytes, filePath)
|
||||
y, err := limayaml.LoadWithWarnings(ctx, yBytes, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -121,7 +122,7 @@ func editAction(cmd *cobra.Command, args []string) error {
|
||||
return saveRejectedYAML(yBytes, err)
|
||||
}
|
||||
|
||||
if err := limayaml.ValidateAgainstLatestConfig(yBytes, yContent); err != nil {
|
||||
if err := limayaml.ValidateAgainstLatestConfig(ctx, yBytes, yContent); err != nil {
|
||||
return saveRejectedYAML(yBytes, err)
|
||||
}
|
||||
|
||||
@@ -148,7 +149,6 @@ func editAction(cmd *cobra.Command, args []string) error {
|
||||
if !startNow {
|
||||
return nil
|
||||
}
|
||||
ctx := cmd.Context()
|
||||
err = networks.Reconcile(ctx, inst.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -156,7 +156,7 @@ func editAction(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// store.Inspect() syncs values between inst.YAML and the store.
|
||||
// This call applies the validated template to the store.
|
||||
inst, err = store.Inspect(inst.Name)
|
||||
inst, err = store.Inspect(ctx, inst.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -30,13 +30,14 @@ func newFactoryResetCommand() *cobra.Command {
|
||||
return resetCommand
|
||||
}
|
||||
|
||||
func factoryResetAction(_ *cobra.Command, args []string) error {
|
||||
func factoryResetAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := DefaultInstanceName
|
||||
if len(args) > 0 {
|
||||
instName = args[0]
|
||||
}
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
logrus.Infof("Instance %q not found", instName)
|
||||
@@ -69,7 +70,7 @@ func factoryResetAction(_ *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
// Regenerate the cloud-config.yaml, to reflect any changes to the global _config
|
||||
if err := cidata.GenerateCloudConfig(inst.Dir, instName, inst.Config); err != nil {
|
||||
if err := cidata.GenerateCloudConfig(ctx, inst.Dir, instName, inst.Config); err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
|
||||
if showProgress {
|
||||
opts = append(opts, hostagent.WithCloudInitProgress(showProgress))
|
||||
}
|
||||
ha, err := hostagent.New(instName, stdout, signalCh, opts...)
|
||||
ha, err := hostagent.New(ctx, instName, stdout, signalCh, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-1
@@ -24,7 +24,8 @@ func newInfoCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func infoAction(cmd *cobra.Command, _ []string) error {
|
||||
info, err := limainfo.New()
|
||||
ctx := cmd.Context()
|
||||
info, err := limainfo.New(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-1
@@ -91,6 +91,7 @@ func (unmatchedInstancesError) ExitCode() int {
|
||||
}
|
||||
|
||||
func listAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
quiet, err := cmd.Flags().GetBool("quiet")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -173,7 +174,7 @@ func listAction(cmd *cobra.Command, args []string) error {
|
||||
// get the state and config for all the requested instances
|
||||
var instances []*store.Instance
|
||||
for _, instanceName := range instanceNames {
|
||||
instance, err := store.Inspect(instanceName)
|
||||
instance, err := store.Inspect(ctx, instanceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load instance %s: %w", instanceName, err)
|
||||
}
|
||||
|
||||
@@ -27,10 +27,11 @@ The instance is not being protected against removal via '/bin/rm', Finder, etc.`
|
||||
return protectCommand
|
||||
}
|
||||
|
||||
func protectAction(_ *cobra.Command, args []string) error {
|
||||
func protectAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
var errs []error
|
||||
for _, instName := range args {
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to inspect instance %q: %w", instName, err))
|
||||
continue
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"maps"
|
||||
"os"
|
||||
|
||||
@@ -30,6 +31,7 @@ func newPruneCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func pruneAction(cmd *cobra.Command, _ []string) error {
|
||||
ctx := cmd.Context()
|
||||
keepReferred, err := cmd.Flags().GetBool("keep-referred")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -44,7 +46,7 @@ func pruneAction(cmd *cobra.Command, _ []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
knownLocations, err := knownLocations()
|
||||
knownLocations, err := knownLocations(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -62,7 +64,7 @@ func pruneAction(cmd *cobra.Command, _ []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func knownLocations() (map[string]limayaml.File, error) {
|
||||
func knownLocations(ctx context.Context) (map[string]limayaml.File, error) {
|
||||
locations := make(map[string]limayaml.File)
|
||||
|
||||
// Collect locations from instances
|
||||
@@ -71,7 +73,7 @@ func knownLocations() (map[string]limayaml.File, error) {
|
||||
return nil, err
|
||||
}
|
||||
for _, instanceName := range instances {
|
||||
instance, err := store.Inspect(instanceName)
|
||||
instance, err := store.Inspect(ctx, instanceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -88,7 +90,7 @@ func knownLocations() (map[string]limayaml.File, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y, err := limayaml.Load(b, t.Name)
|
||||
y, err := limayaml.Load(ctx, b, t.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -25,12 +25,13 @@ func newRestartCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func restartAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := DefaultInstanceName
|
||||
if len(args) > 0 {
|
||||
instName = args[0]
|
||||
}
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -40,7 +41,6 @@ func restartAction(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
if force {
|
||||
return instance.RestartForcibly(ctx, inst)
|
||||
}
|
||||
|
||||
+10
-10
@@ -4,6 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -78,7 +79,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName)
|
||||
@@ -95,8 +96,6 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
|
||||
err = networks.Reconcile(ctx, inst.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -107,7 +106,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
inst, err = store.Inspect(instName)
|
||||
inst, err = store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -146,7 +145,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
} else if len(inst.Config.Mounts) > 0 || inst.VMType == limayaml.WSL2 {
|
||||
hostCurrentDir, err := os.Getwd()
|
||||
if err == nil && runtime.GOOS == "windows" {
|
||||
hostCurrentDir, err = mountDirFromWindowsDir(inst, hostCurrentDir)
|
||||
hostCurrentDir, err = mountDirFromWindowsDir(ctx, inst, hostCurrentDir)
|
||||
}
|
||||
if err == nil {
|
||||
changeDirCmd = fmt.Sprintf("cd %s", shellescape.Quote(hostCurrentDir))
|
||||
@@ -156,7 +155,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
hostHomeDir, err := os.UserHomeDir()
|
||||
if err == nil && runtime.GOOS == "windows" {
|
||||
hostHomeDir, err = mountDirFromWindowsDir(inst, hostHomeDir)
|
||||
hostHomeDir, err = mountDirFromWindowsDir(ctx, inst, hostHomeDir)
|
||||
}
|
||||
if err == nil {
|
||||
changeDirCmd = fmt.Sprintf("%s || cd %s", changeDirCmd, shellescape.Quote(hostHomeDir))
|
||||
@@ -221,6 +220,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
sshOpts, err := sshutil.SSHOpts(
|
||||
ctx,
|
||||
sshExe,
|
||||
inst.Dir,
|
||||
*inst.Config.User.Name,
|
||||
@@ -244,7 +244,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
logLevel := "ERROR"
|
||||
// For versions older than OpenSSH 8.9p, LogLevel=QUIET was needed to
|
||||
// avoid the "Shared connection to 127.0.0.1 closed." message with -t.
|
||||
olderSSH := sshutil.DetectOpenSSHVersion(sshExe).LessThan(*semver.New("8.9.0"))
|
||||
olderSSH := sshutil.DetectOpenSSHVersion(ctx, sshExe).LessThan(*semver.New("8.9.0"))
|
||||
if olderSSH {
|
||||
logLevel = "QUIET"
|
||||
}
|
||||
@@ -265,12 +265,12 @@ func shellAction(cmd *cobra.Command, args []string) error {
|
||||
return sshCmd.Run()
|
||||
}
|
||||
|
||||
func mountDirFromWindowsDir(inst *store.Instance, dir string) (string, error) {
|
||||
func mountDirFromWindowsDir(ctx context.Context, inst *store.Instance, dir string) (string, error) {
|
||||
if inst.VMType == limayaml.WSL2 {
|
||||
distroName := "lima-" + inst.Name
|
||||
return ioutilx.WindowsSubsystemPathForLinux(dir, distroName)
|
||||
return ioutilx.WindowsSubsystemPathForLinux(ctx, dir, distroName)
|
||||
}
|
||||
return ioutilx.WindowsSubsystemPath(dir)
|
||||
return ioutilx.WindowsSubsystemPath(ctx, dir)
|
||||
}
|
||||
|
||||
func shellBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
|
||||
@@ -77,13 +77,14 @@ Instead, use 'ssh -F %s/default/ssh.config lima-default' .
|
||||
}
|
||||
|
||||
func showSSHAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
format, err := cmd.Flags().GetString("format")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
instName := args[0]
|
||||
w := cmd.OutOrStdout()
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName)
|
||||
@@ -97,6 +98,7 @@ func showSSHAction(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
opts, err := sshutil.SSHOpts(
|
||||
ctx,
|
||||
sshExe,
|
||||
inst.Dir,
|
||||
*inst.Config.User.Name,
|
||||
|
||||
@@ -47,9 +47,10 @@ func newSnapshotCreateCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func snapshotCreateAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := args[0]
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -63,7 +64,6 @@ func snapshotCreateAction(cmd *cobra.Command, args []string) error {
|
||||
return errors.New("expected tag")
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
return snapshot.Save(ctx, inst, tag)
|
||||
}
|
||||
|
||||
@@ -82,9 +82,10 @@ func newSnapshotDeleteCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func snapshotDeleteAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := args[0]
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -98,7 +99,6 @@ func snapshotDeleteAction(cmd *cobra.Command, args []string) error {
|
||||
return errors.New("expected tag")
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
return snapshot.Del(ctx, inst, tag)
|
||||
}
|
||||
|
||||
@@ -117,9 +117,10 @@ func newSnapshotApplyCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func snapshotApplyAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := args[0]
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -133,7 +134,6 @@ func snapshotApplyAction(cmd *cobra.Command, args []string) error {
|
||||
return errors.New("expected tag")
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
return snapshot.Load(ctx, inst, tag)
|
||||
}
|
||||
|
||||
@@ -152,9 +152,10 @@ func newSnapshotListCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func snapshotListAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := args[0]
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -163,7 +164,6 @@ func snapshotListAction(cmd *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := cmd.Context()
|
||||
out, err := snapshot.List(ctx, inst)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -18,12 +18,13 @@ import (
|
||||
)
|
||||
|
||||
func startAtLoginAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := DefaultInstanceName
|
||||
if len(args) > 0 {
|
||||
instName = args[0]
|
||||
}
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
logrus.Infof("Instance %q not found", instName)
|
||||
@@ -38,13 +39,13 @@ func startAtLoginAction(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
if startAtLogin {
|
||||
if err := autostart.CreateStartAtLoginEntry(runtime.GOOS, inst.Name, inst.Dir); err != nil {
|
||||
if err := autostart.CreateStartAtLoginEntry(ctx, runtime.GOOS, inst.Name, inst.Dir); err != nil {
|
||||
logrus.WithError(err).Warnf("Can't create an autostart file for instance %q", inst.Name)
|
||||
} else {
|
||||
logrus.Infof("The autostart file %q has been created or updated", autostart.GetFilePath(runtime.GOOS, inst.Name))
|
||||
}
|
||||
} else {
|
||||
deleted, err := autostart.DeleteStartAtLoginEntry(runtime.GOOS, instName)
|
||||
deleted, err := autostart.DeleteStartAtLoginEntry(ctx, runtime.GOOS, instName)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warnf("The autostart file %q could not be deleted", instName)
|
||||
} else if deleted {
|
||||
|
||||
@@ -104,6 +104,7 @@ See the examples in 'limactl create --help'.
|
||||
}
|
||||
|
||||
func loadOrCreateInstance(cmd *cobra.Command, args []string, createOnly bool) (*store.Instance, error) {
|
||||
ctx := cmd.Context()
|
||||
var arg string // can be empty
|
||||
if len(args) > 0 {
|
||||
arg = args[0]
|
||||
@@ -171,7 +172,7 @@ func loadOrCreateInstance(cmd *cobra.Command, args []string, createOnly bool) (*
|
||||
tmpl.Name = arg
|
||||
}
|
||||
// store.Inspect() will validate the template name (in case it has been set to arg)
|
||||
inst, err := store.Inspect(tmpl.Name)
|
||||
inst, err := store.Inspect(ctx, tmpl.Name)
|
||||
if err == nil {
|
||||
if createOnly {
|
||||
return nil, fmt.Errorf("instance %q already exists", tmpl.Name)
|
||||
@@ -183,7 +184,7 @@ func loadOrCreateInstance(cmd *cobra.Command, args []string, createOnly bool) (*
|
||||
}
|
||||
if len(yqExprs) > 0 {
|
||||
yq := yqutil.Join(yqExprs)
|
||||
inst, err = applyYQExpressionToExistingInstance(inst, yq)
|
||||
inst, err = applyYQExpressionToExistingInstance(ctx, inst, yq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to apply yq expression %q to instance %q: %w", yq, tmpl.Name, err)
|
||||
}
|
||||
@@ -209,7 +210,7 @@ func loadOrCreateInstance(cmd *cobra.Command, args []string, createOnly bool) (*
|
||||
}
|
||||
if createOnly {
|
||||
// store.Inspect() will also validate the instance name
|
||||
if _, err := store.Inspect(tmpl.Name); err == nil {
|
||||
if _, err := store.Inspect(ctx, tmpl.Name); err == nil {
|
||||
return nil, fmt.Errorf("instance %q already exists", tmpl.Name)
|
||||
}
|
||||
} else if err := store.ValidateInstName(tmpl.Name); err != nil {
|
||||
@@ -241,7 +242,7 @@ func loadOrCreateInstance(cmd *cobra.Command, args []string, createOnly bool) (*
|
||||
return instance.Create(cmd.Context(), tmpl.Name, tmpl.Bytes, saveBrokenYAML)
|
||||
}
|
||||
|
||||
func applyYQExpressionToExistingInstance(inst *store.Instance, yq string) (*store.Instance, error) {
|
||||
func applyYQExpressionToExistingInstance(ctx context.Context, inst *store.Instance, yq string) (*store.Instance, error) {
|
||||
if strings.TrimSpace(yq) == "" {
|
||||
return inst, nil
|
||||
}
|
||||
@@ -255,7 +256,7 @@ func applyYQExpressionToExistingInstance(inst *store.Instance, yq string) (*stor
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y, err := limayaml.Load(yBytes, filePath)
|
||||
y, err := limayaml.Load(ctx, yBytes, filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -271,7 +272,7 @@ func applyYQExpressionToExistingInstance(inst *store.Instance, yq string) (*stor
|
||||
return nil, err
|
||||
}
|
||||
// Reload
|
||||
return store.Inspect(inst.Name)
|
||||
return store.Inspect(ctx, inst.Name)
|
||||
}
|
||||
|
||||
func modifyInPlace(st *limatmpl.Template, yq string) error {
|
||||
@@ -331,7 +332,7 @@ func chooseNextCreatorState(ctx context.Context, tmpl *limatmpl.Template, yq str
|
||||
hdr += "\n"
|
||||
hdr += editutil.GenerateEditorWarningHeader()
|
||||
var err error
|
||||
tmpl.Bytes, err = editutil.OpenEditor(tmpl.Bytes, hdr)
|
||||
tmpl.Bytes, err = editutil.OpenEditor(ctx, tmpl.Bytes, hdr)
|
||||
tmpl.Config = nil
|
||||
if err != nil {
|
||||
return tmpl, err
|
||||
|
||||
+2
-2
@@ -26,12 +26,13 @@ func newStopCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func stopAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
instName := DefaultInstanceName
|
||||
if len(args) > 0 {
|
||||
instName = args[0]
|
||||
}
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -40,7 +41,6 @@ func stopAction(cmd *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := cmd.Context()
|
||||
if force {
|
||||
instance.StopForcibly(inst)
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
)
|
||||
|
||||
func sudoersAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
nwCfg, err := networks.LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -29,7 +31,7 @@ func sudoersAction(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
if check {
|
||||
return verifySudoAccess(nwCfg, args, cmd.OutOrStdout())
|
||||
return verifySudoAccess(ctx, nwCfg, args, cmd.OutOrStdout())
|
||||
}
|
||||
switch len(args) {
|
||||
case 0:
|
||||
@@ -47,7 +49,7 @@ func sudoersAction(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifySudoAccess(nwCfg networks.Config, args []string, stdout io.Writer) error {
|
||||
func verifySudoAccess(ctx context.Context, nwCfg networks.Config, args []string, stdout io.Writer) error {
|
||||
var file string
|
||||
switch len(args) {
|
||||
case 0:
|
||||
@@ -61,7 +63,7 @@ func verifySudoAccess(nwCfg networks.Config, args []string, stdout io.Writer) er
|
||||
default:
|
||||
return errors.New("can check only a single sudoers file")
|
||||
}
|
||||
if err := nwCfg.VerifySudoAccess(file); err != nil {
|
||||
if err := nwCfg.VerifySudoAccess(ctx, file); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(stdout, "%q is up-to-date (or sudo doesn't require a password)\n", file)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -74,7 +75,7 @@ func newTemplateCopyCommand() *cobra.Command {
|
||||
return templateCopyCommand
|
||||
}
|
||||
|
||||
func fillDefaults(tmpl *limatmpl.Template) error {
|
||||
func fillDefaults(ctx context.Context, tmpl *limatmpl.Template) error {
|
||||
limaDir, err := dirnames.LimaDir()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -82,7 +83,7 @@ func fillDefaults(tmpl *limatmpl.Template) error {
|
||||
// Load() will merge the template with override.yaml and default.yaml via FillDefaults().
|
||||
// FillDefaults() needs the potential instance directory to validate host templates using {{.Dir}}.
|
||||
filePath := filepath.Join(limaDir, tmpl.Name+".yaml")
|
||||
tmpl.Config, err = limayaml.Load(tmpl.Bytes, filePath)
|
||||
tmpl.Config, err = limayaml.Load(ctx, tmpl.Bytes, filePath)
|
||||
if err == nil {
|
||||
tmpl.Bytes, err = limayaml.Marshal(tmpl.Config, false)
|
||||
}
|
||||
@@ -90,6 +91,7 @@ func fillDefaults(tmpl *limatmpl.Template) error {
|
||||
}
|
||||
|
||||
func templateCopyAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
source := args[0]
|
||||
target := args[1]
|
||||
embed, err := cmd.Flags().GetBool("embed")
|
||||
@@ -137,7 +139,7 @@ func templateCopyAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
if fill {
|
||||
if err := fillDefaults(tmpl); err != nil {
|
||||
if err := fillDefaults(ctx, tmpl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -177,6 +179,7 @@ func newTemplateYQCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func templateYQAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
locator := args[0]
|
||||
expr := args[1]
|
||||
tmpl, err := limatmpl.Read(cmd.Context(), "", locator)
|
||||
@@ -189,7 +192,7 @@ func templateYQAction(cmd *cobra.Command, args []string) error {
|
||||
if err := tmpl.Embed(cmd.Context(), true, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fillDefaults(tmpl); err != nil {
|
||||
if err := fillDefaults(ctx, tmpl); err != nil {
|
||||
return err
|
||||
}
|
||||
out, err := yqutil.EvaluateExpressionPlain(expr, string(tmpl.Bytes))
|
||||
@@ -211,6 +214,7 @@ func newTemplateValidateCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func templateValidateAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
fill, err := cmd.Flags().GetBool("fill")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -238,7 +242,7 @@ func templateValidateAction(cmd *cobra.Command, args []string) error {
|
||||
// Load() will merge the template with override.yaml and default.yaml via FillDefaults().
|
||||
// FillDefaults() needs the potential instance directory to validate host templates using {{.Dir}}.
|
||||
filePath := filepath.Join(limaDir, tmpl.Name+".yaml")
|
||||
y, err := limayaml.Load(tmpl.Bytes, filePath)
|
||||
y, err := limayaml.Load(ctx, tmpl.Bytes, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func tunnelAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
stdout, stderr := cmd.OutOrStdout(), cmd.ErrOrStderr()
|
||||
instName := args[0]
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName)
|
||||
@@ -89,6 +89,7 @@ func tunnelAction(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
sshOpts, err := sshutil.SSHOpts(
|
||||
ctx,
|
||||
sshExe,
|
||||
inst.Dir,
|
||||
*inst.Config.User.Name,
|
||||
|
||||
@@ -25,10 +25,11 @@ func newUnprotectCommand() *cobra.Command {
|
||||
return unprotectCommand
|
||||
}
|
||||
|
||||
func unprotectAction(_ *cobra.Command, args []string) error {
|
||||
func unprotectAction(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
var errs []error
|
||||
for _, instName := range args {
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to inspect instance %q: %w", instName, err))
|
||||
continue
|
||||
|
||||
@@ -26,7 +26,7 @@ var systemdTemplate string
|
||||
var launchdTemplate string
|
||||
|
||||
// CreateStartAtLoginEntry respect host OS arch and create unit file.
|
||||
func CreateStartAtLoginEntry(hostOS, instName, workDir string) error {
|
||||
func CreateStartAtLoginEntry(ctx context.Context, hostOS, instName, workDir string) error {
|
||||
unitPath := GetFilePath(hostOS, instName)
|
||||
if _, err := os.Stat(unitPath); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
@@ -41,17 +41,17 @@ func CreateStartAtLoginEntry(hostOS, instName, workDir string) error {
|
||||
if err := os.WriteFile(unitPath, tmpl, 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
return enableDisableService("enable", hostOS, GetFilePath(hostOS, instName))
|
||||
return enableDisableService(ctx, "enable", hostOS, GetFilePath(hostOS, instName))
|
||||
}
|
||||
|
||||
// DeleteStartAtLoginEntry respect host OS arch and delete unit file.
|
||||
// Return true, nil if unit file has been deleted.
|
||||
func DeleteStartAtLoginEntry(hostOS, instName string) (bool, error) {
|
||||
func DeleteStartAtLoginEntry(ctx context.Context, hostOS, instName string) (bool, error) {
|
||||
unitPath := GetFilePath(hostOS, instName)
|
||||
if _, err := os.Stat(unitPath); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := enableDisableService("disable", hostOS, GetFilePath(hostOS, instName)); err != nil {
|
||||
if err := enableDisableService(ctx, "disable", hostOS, GetFilePath(hostOS, instName)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := os.Remove(unitPath); err != nil {
|
||||
@@ -78,8 +78,7 @@ func GetFilePath(hostOS, instName string) string {
|
||||
return fileTmpl
|
||||
}
|
||||
|
||||
func enableDisableService(action, hostOS, serviceWithPath string) error {
|
||||
ctx := context.TODO()
|
||||
func enableDisableService(ctx context.Context, action, hostOS, serviceWithPath string) error {
|
||||
// Get filename without extension
|
||||
filename := strings.TrimSuffix(path.Base(serviceWithPath), filepath.Ext(path.Base(serviceWithPath)))
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package cidata
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -115,7 +116,7 @@ func setupEnv(instConfigEnv map[string]string, propagateProxyEnv bool, slirpGate
|
||||
return env, nil
|
||||
}
|
||||
|
||||
func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort, vsockPort int, virtioPort string) (*TemplateArgs, error) {
|
||||
func templateArgs(ctx context.Context, bootScripts bool, instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort, vsockPort int, virtioPort string) (*TemplateArgs, error) {
|
||||
if err := limayaml.Validate(instConfig, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -174,7 +175,7 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
|
||||
// change instance id on every boot so network config will be processed again
|
||||
args.IID = fmt.Sprintf("iid-%d", time.Now().Unix())
|
||||
|
||||
pubKeys, err := sshutil.DefaultPubKeys(*instConfig.SSH.LoadDotSSHPubKeys)
|
||||
pubKeys, err := sshutil.DefaultPubKeys(ctx, *instConfig.SSH.LoadDotSSHPubKeys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -332,8 +333,8 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
|
||||
return &args, nil
|
||||
}
|
||||
|
||||
func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) error {
|
||||
args, err := templateArgs(false, instDir, name, instConfig, 0, 0, 0, "")
|
||||
func GenerateCloudConfig(ctx context.Context, instDir, name string, instConfig *limayaml.LimaYAML) error {
|
||||
args, err := templateArgs(ctx, false, instDir, name, instConfig, 0, 0, 0, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -355,8 +356,8 @@ func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) er
|
||||
return os.WriteFile(filepath.Join(instDir, filenames.CloudConfig), config, 0o444)
|
||||
}
|
||||
|
||||
func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, guestAgentBinary, nerdctlArchive string, vsockPort int, virtioPort string) error {
|
||||
args, err := templateArgs(true, instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort)
|
||||
func GenerateISO9660(ctx context.Context, instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, guestAgentBinary, nerdctlArchive string, vsockPort int, virtioPort string) error {
|
||||
args, err := templateArgs(ctx, true, instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// Lifecycle defines basic lifecycle operations.
|
||||
type Lifecycle interface {
|
||||
// Validate returns error if the current driver isn't support for given config
|
||||
Validate() error
|
||||
Validate(_ context.Context) error
|
||||
|
||||
// Initialize is called on creating the instance for initialization.
|
||||
// (e.g., creating "vz-identifier" file)
|
||||
|
||||
+2
-3
@@ -17,12 +17,11 @@ import (
|
||||
"github.com/lima-vm/lima/v2/pkg/store"
|
||||
)
|
||||
|
||||
func (d *DriverClient) Validate() error {
|
||||
func (d *DriverClient) Validate(ctx context.Context) error {
|
||||
d.logger.Debug("Validating driver for the given config")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, err := d.DriverSvc.Validate(ctx, &emptypb.Empty{})
|
||||
if err != nil {
|
||||
d.logger.Errorf("Validation failed: %v", err)
|
||||
|
||||
+2
-2
@@ -117,9 +117,9 @@ func (s *DriverServer) GetInfo(_ context.Context, _ *emptypb.Empty) (*pb.InfoRes
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *DriverServer) Validate(_ context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
|
||||
func (s *DriverServer) Validate(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
|
||||
s.logger.Debugf("Received Validate request")
|
||||
err := s.driver.Validate()
|
||||
err := s.driver.Validate(ctx)
|
||||
if err != nil {
|
||||
s.logger.Errorf("Validation failed: %v", err)
|
||||
return empty, err
|
||||
|
||||
Vendored
+1
-2
@@ -50,8 +50,7 @@ func (t *listenerTracker) Accept() (net.Conn, error) {
|
||||
return c, err
|
||||
}
|
||||
|
||||
func Serve(driver driver.Driver) {
|
||||
ctx := context.TODO()
|
||||
func Serve(ctx context.Context, driver driver.Driver) {
|
||||
logger := logrus.New()
|
||||
logger.SetLevel(logrus.DebugLevel)
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ import (
|
||||
|
||||
// IsSigned returns an error if the binary is not signed, or the sign is invalid,
|
||||
// or not associated with the "com.apple.security.hypervisor" entitlement.
|
||||
func IsSigned(qExe string) error {
|
||||
ctx := context.TODO()
|
||||
func IsSigned(ctx context.Context, qExe string) error {
|
||||
cmd := exec.CommandContext(ctx, "codesign", "--verify", qExe)
|
||||
out, err := cmd.CombinedOutput()
|
||||
logrus.WithError(err).Debugf("Executed %v: out=%q", cmd.Args, string(out))
|
||||
@@ -40,8 +39,7 @@ func IsSigned(qExe string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Sign(qExe string) error {
|
||||
ctx := context.TODO()
|
||||
func Sign(ctx context.Context, qExe string) error {
|
||||
ent, err := os.CreateTemp("", "lima-qemu-entitlements-*.xml")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create a temporary file for signing QEMU binary: %w", err)
|
||||
@@ -85,8 +83,8 @@ func isColimaWrapper__useThisFunctionOnlyForPrintingHints__(qExe string) bool {
|
||||
//
|
||||
// On Homebrew, QEMU binaries are usually already signed, but Homebrew's signing infrastructure is broken for Intel as of August 2023.
|
||||
// https://github.com/lima-vm/lima/issues/1742
|
||||
func AskToSignIfNotSignedProperly(qExe string) {
|
||||
if isSignedErr := IsSigned(qExe); isSignedErr != nil {
|
||||
func AskToSignIfNotSignedProperly(ctx context.Context, qExe string) {
|
||||
if isSignedErr := IsSigned(ctx, qExe); isSignedErr != nil {
|
||||
logrus.WithError(isSignedErr).Warnf("QEMU binary %q does not seem properly signed with the \"com.apple.security.hypervisor\" entitlement", qExe)
|
||||
if isColimaWrapper__useThisFunctionOnlyForPrintingHints__(qExe) {
|
||||
logrus.Info("Hint: the warning above is usually negligible for colima ( Printed due to https://github.com/abiosoft/colima/issues/796 )")
|
||||
@@ -101,7 +99,7 @@ func AskToSignIfNotSignedProperly(qExe string) {
|
||||
}
|
||||
}
|
||||
if ans {
|
||||
if signErr := Sign(qExe); signErr != nil {
|
||||
if signErr := Sign(ctx, qExe); signErr != nil {
|
||||
logrus.WithError(signErr).Warnf("Failed to sign %q", qExe)
|
||||
} else {
|
||||
logrus.Infof("Successfully signed %q with the \"com.apple.security.hypervisor\" entitlement", qExe)
|
||||
|
||||
+16
-20
@@ -103,7 +103,7 @@ func EnsureDisk(ctx context.Context, cfg Config) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
baseDiskInfo, err := qemuimgutil.GetInfo(baseDisk)
|
||||
baseDiskInfo, err := qemuimgutil.GetInfo(ctx, baseDisk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get the information of base disk %q: %w", baseDisk, err)
|
||||
}
|
||||
@@ -149,8 +149,7 @@ func sendHmpCommand(cfg Config, cmd, tag string) (string, error) {
|
||||
return rawClient.HumanMonitorCommand(hmc, nil)
|
||||
}
|
||||
|
||||
func execImgCommand(cfg Config, args ...string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func execImgCommand(ctx context.Context, cfg Config, args ...string) (string, error) {
|
||||
diffDisk := filepath.Join(cfg.InstanceDir, filenames.DiffDisk)
|
||||
args = append(args, diffDisk)
|
||||
logrus.Debugf("Running qemu-img %v command", args)
|
||||
@@ -162,7 +161,7 @@ func execImgCommand(cfg Config, args ...string) (string, error) {
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
func Del(cfg Config, run bool, tag string) error {
|
||||
func Del(ctx context.Context, cfg Config, run bool, tag string) error {
|
||||
if run {
|
||||
out, err := sendHmpCommand(cfg, "delvm", tag)
|
||||
// there can still be output, even if no error!
|
||||
@@ -172,11 +171,11 @@ func Del(cfg Config, run bool, tag string) error {
|
||||
return err
|
||||
}
|
||||
// -d deletes a snapshot
|
||||
_, err := execImgCommand(cfg, "snapshot", "-d", tag)
|
||||
_, err := execImgCommand(ctx, cfg, "snapshot", "-d", tag)
|
||||
return err
|
||||
}
|
||||
|
||||
func Save(cfg Config, run bool, tag string) error {
|
||||
func Save(ctx context.Context, cfg Config, run bool, tag string) error {
|
||||
if run {
|
||||
out, err := sendHmpCommand(cfg, "savevm", tag)
|
||||
// there can still be output, even if no error!
|
||||
@@ -186,11 +185,11 @@ func Save(cfg Config, run bool, tag string) error {
|
||||
return err
|
||||
}
|
||||
// -c creates a snapshot
|
||||
_, err := execImgCommand(cfg, "snapshot", "-c", tag)
|
||||
_, err := execImgCommand(ctx, cfg, "snapshot", "-c", tag)
|
||||
return err
|
||||
}
|
||||
|
||||
func Load(cfg Config, run bool, tag string) error {
|
||||
func Load(ctx context.Context, cfg Config, run bool, tag string) error {
|
||||
if run {
|
||||
out, err := sendHmpCommand(cfg, "loadvm", tag)
|
||||
// there can still be output, even if no error!
|
||||
@@ -200,12 +199,12 @@ func Load(cfg Config, run bool, tag string) error {
|
||||
return err
|
||||
}
|
||||
// -a applies a snapshot
|
||||
_, err := execImgCommand(cfg, "snapshot", "-a", tag)
|
||||
_, err := execImgCommand(ctx, cfg, "snapshot", "-a", tag)
|
||||
return err
|
||||
}
|
||||
|
||||
// List returns a space-separated list of all snapshots, with header and newlines.
|
||||
func List(cfg Config, run bool) (string, error) {
|
||||
func List(ctx context.Context, cfg Config, run bool) (string, error) {
|
||||
if run {
|
||||
out, err := sendHmpCommand(cfg, "info", "snapshots")
|
||||
if err == nil {
|
||||
@@ -217,7 +216,7 @@ func List(cfg Config, run bool) (string, error) {
|
||||
}
|
||||
// -l lists all snapshots
|
||||
args := []string{"snapshot", "-l"}
|
||||
out, err := execImgCommand(cfg, args...)
|
||||
out, err := execImgCommand(ctx, cfg, args...)
|
||||
if err == nil {
|
||||
// remove the redundant heading, result is not machine-parseable
|
||||
out = strings.Replace(out, "Snapshot list:\n", "", 1)
|
||||
@@ -288,9 +287,8 @@ type features struct {
|
||||
CPUHelp []byte
|
||||
}
|
||||
|
||||
func inspectFeatures(exe, machine string) (*features, error) {
|
||||
func inspectFeatures(ctx context.Context, exe, machine string) (*features, error) {
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
f features
|
||||
stdout bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
@@ -474,12 +472,12 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
features, err := inspectFeatures(exe, qemuMachine(*y.Arch))
|
||||
features, err := inspectFeatures(ctx, exe, qemuMachine(*y.Arch))
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
version, err := getQemuVersion(exe)
|
||||
version, err := getQemuVersion(ctx, exe)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warning("Failed to detect QEMU version")
|
||||
} else {
|
||||
@@ -720,7 +718,7 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
|
||||
if diskSize, _ := units.RAMInBytes(*cfg.LimaYAML.Disk); diskSize > 0 {
|
||||
args = append(args, "-drive", fmt.Sprintf("file=%s,if=virtio,discard=on", diffDisk))
|
||||
} else if !isBaseDiskCDROM {
|
||||
baseDiskInfo, err := qemuimgutil.GetInfo(baseDisk)
|
||||
baseDiskInfo, err := qemuimgutil.GetInfo(ctx, baseDisk)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to get the information of %q: %w", baseDisk, err)
|
||||
}
|
||||
@@ -977,8 +975,7 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
|
||||
return exe, args, nil
|
||||
}
|
||||
|
||||
func FindVirtiofsd(qemuExe string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func FindVirtiofsd(ctx context.Context, qemuExe string) (string, error) {
|
||||
type vhostUserBackend struct {
|
||||
BackendType string `json:"type"`
|
||||
Binary string `json:"binary"`
|
||||
@@ -1135,9 +1132,8 @@ func parseQemuVersion(output string) (*semver.Version, error) {
|
||||
return &semver.Version{}, fmt.Errorf("failed to parse %v", output)
|
||||
}
|
||||
|
||||
func getQemuVersion(qemuExe string) (*semver.Version, error) {
|
||||
func getQemuVersion(ctx context.Context, qemuExe string) (*semver.Version, error) {
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
stdout bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
)
|
||||
|
||||
@@ -73,9 +73,9 @@ func (l *LimaQemuDriver) Configure(inst *store.Instance) *driver.ConfiguredDrive
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LimaQemuDriver) Validate() error {
|
||||
func (l *LimaQemuDriver) Validate(ctx context.Context) error {
|
||||
if runtime.GOOS == "darwin" {
|
||||
if err := l.checkBinarySignature(); err != nil {
|
||||
if err := l.checkBinarySignature(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func (l *LimaQemuDriver) Start(_ context.Context) (chan error, error) {
|
||||
|
||||
var vhostCmds []*exec.Cmd
|
||||
if *l.Instance.Config.MountType == limayaml.VIRTIOFS {
|
||||
vhostExe, err := FindVirtiofsd(qExe)
|
||||
vhostExe, err := FindVirtiofsd(ctx, qExe)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -270,7 +270,7 @@ func waitFileExists(path string, timeout time.Duration) error {
|
||||
|
||||
// Ask the user to sign the qemu binary with the "com.apple.security.hypervisor" if needed.
|
||||
// Workaround for https://github.com/lima-vm/lima/issues/1742
|
||||
func (l *LimaQemuDriver) checkBinarySignature() error {
|
||||
func (l *LimaQemuDriver) checkBinarySignature(ctx context.Context) error {
|
||||
macOSProductVersion, err := osutil.ProductVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -282,7 +282,7 @@ func (l *LimaQemuDriver) checkBinarySignature() error {
|
||||
return fmt.Errorf("failed to find the QEMU binary for the architecture %q: %w", l.Instance.Arch, err)
|
||||
}
|
||||
if accel := Accel(l.Instance.Arch); accel == "hvf" {
|
||||
entitlementutil.AskToSignIfNotSignedProperly(qExe)
|
||||
entitlementutil.AskToSignIfNotSignedProperly(ctx, qExe)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,40 +434,40 @@ func logPipeRoutine(r io.Reader, header string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LimaQemuDriver) DeleteSnapshot(_ context.Context, tag string) error {
|
||||
func (l *LimaQemuDriver) DeleteSnapshot(ctx context.Context, tag string) error {
|
||||
qCfg := Config{
|
||||
Name: l.Instance.Name,
|
||||
InstanceDir: l.Instance.Dir,
|
||||
LimaYAML: l.Instance.Config,
|
||||
}
|
||||
return Del(qCfg, l.Instance.Status == store.StatusRunning, tag)
|
||||
return Del(ctx, qCfg, l.Instance.Status == store.StatusRunning, tag)
|
||||
}
|
||||
|
||||
func (l *LimaQemuDriver) CreateSnapshot(_ context.Context, tag string) error {
|
||||
func (l *LimaQemuDriver) CreateSnapshot(ctx context.Context, tag string) error {
|
||||
qCfg := Config{
|
||||
Name: l.Instance.Name,
|
||||
InstanceDir: l.Instance.Dir,
|
||||
LimaYAML: l.Instance.Config,
|
||||
}
|
||||
return Save(qCfg, l.Instance.Status == store.StatusRunning, tag)
|
||||
return Save(ctx, qCfg, l.Instance.Status == store.StatusRunning, tag)
|
||||
}
|
||||
|
||||
func (l *LimaQemuDriver) ApplySnapshot(_ context.Context, tag string) error {
|
||||
func (l *LimaQemuDriver) ApplySnapshot(ctx context.Context, tag string) error {
|
||||
qCfg := Config{
|
||||
Name: l.Instance.Name,
|
||||
InstanceDir: l.Instance.Dir,
|
||||
LimaYAML: l.Instance.Config,
|
||||
}
|
||||
return Load(qCfg, l.Instance.Status == store.StatusRunning, tag)
|
||||
return Load(ctx, qCfg, l.Instance.Status == store.StatusRunning, tag)
|
||||
}
|
||||
|
||||
func (l *LimaQemuDriver) ListSnapshots(_ context.Context) (string, error) {
|
||||
func (l *LimaQemuDriver) ListSnapshots(ctx context.Context) (string, error) {
|
||||
qCfg := Config{
|
||||
Name: l.Instance.Name,
|
||||
InstanceDir: l.Instance.Dir,
|
||||
LimaYAML: l.Instance.Config,
|
||||
}
|
||||
return List(qCfg, l.Instance.Status == store.StatusRunning)
|
||||
return List(ctx, qCfg, l.Instance.Status == store.StatusRunning)
|
||||
}
|
||||
|
||||
func (l *LimaQemuDriver) GuestAgentConn(ctx context.Context) (net.Conn, string, error) {
|
||||
|
||||
@@ -18,14 +18,14 @@ import (
|
||||
"github.com/lima-vm/lima/v2/pkg/store/filenames"
|
||||
)
|
||||
|
||||
func EnsureDisk(_ context.Context, inst *store.Instance) error {
|
||||
func EnsureDisk(ctx context.Context, inst *store.Instance) error {
|
||||
diffDisk := filepath.Join(inst.Dir, filenames.DiffDisk)
|
||||
if _, err := os.Stat(diffDisk); err == nil || !errors.Is(err, os.ErrNotExist) {
|
||||
// disk is already ensured
|
||||
return err
|
||||
}
|
||||
|
||||
diskUtil := proxyimgutil.NewDiskUtil()
|
||||
diskUtil := proxyimgutil.NewDiskUtil(ctx)
|
||||
|
||||
baseDisk := filepath.Join(inst.Dir, filenames.BaseDisk)
|
||||
|
||||
@@ -44,14 +44,14 @@ func EnsureDisk(_ context.Context, inst *store.Instance) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = diskUtil.MakeSparse(diffDiskF, 0)
|
||||
err = diskUtil.MakeSparse(ctx, diffDiskF, 0)
|
||||
if err != nil {
|
||||
diffDiskF.Close()
|
||||
return fmt.Errorf("failed to create sparse diff disk %q: %w", diffDisk, err)
|
||||
}
|
||||
return diffDiskF.Close()
|
||||
}
|
||||
if err = diskUtil.ConvertToRaw(baseDisk, diffDisk, &diskSize, false); err != nil {
|
||||
if err = diskUtil.ConvertToRaw(ctx, baseDisk, diffDisk, &diskSize, false); err != nil {
|
||||
return fmt.Errorf("failed to convert %q to a raw disk %q: %w", baseDisk, diffDisk, err)
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -43,8 +43,7 @@ func PassFDToUnix(unixSock string) (*os.File, error) {
|
||||
|
||||
// DialQemu support connecting to QEMU supported network stack via unix socket.
|
||||
// Returns os.File, connected dgram connection to be used for vz.
|
||||
func DialQemu(unixSock string) (*os.File, error) {
|
||||
ctx := context.TODO()
|
||||
func DialQemu(ctx context.Context, unixSock string) (*os.File, error) {
|
||||
var dialer net.Dialer
|
||||
unixConn, err := dialer.DialContext(ctx, "unix", unixSock)
|
||||
if err != nil {
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestDialQemu(t *testing.T) {
|
||||
}()
|
||||
|
||||
// Connect to the fake vmnet server.
|
||||
client, err := DialQemu(listener.Addr().String())
|
||||
client, err := DialQemu(t.Context(), listener.Addr().String())
|
||||
assert.NilError(t, err)
|
||||
t.Log("Connected to fake vment server")
|
||||
|
||||
|
||||
+10
-10
@@ -57,7 +57,7 @@ func startVM(ctx context.Context, inst *store.Instance, sshLocalPort int) (*virt
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
machine, err := createVM(inst)
|
||||
machine, err := createVM(ctx, inst)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -161,7 +161,7 @@ func startUsernet(ctx context.Context, inst *store.Instance) (*usernet.Client, e
|
||||
return usernet.NewClient(endpointSock, subnetIP), err
|
||||
}
|
||||
|
||||
func createVM(inst *store.Instance) (*vz.VirtualMachine, error) {
|
||||
func createVM(ctx context.Context, inst *store.Instance) (*vz.VirtualMachine, error) {
|
||||
vmConfig, err := createInitialConfig(inst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -175,11 +175,11 @@ func createVM(inst *store.Instance) (*vz.VirtualMachine, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = attachNetwork(inst, vmConfig); err != nil {
|
||||
if err = attachNetwork(ctx, inst, vmConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = attachDisks(inst, vmConfig); err != nil {
|
||||
if err = attachDisks(ctx, inst, vmConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ func newVirtioNetworkDeviceConfiguration(attachment vz.NetworkDeviceAttachment,
|
||||
return networkConfig, nil
|
||||
}
|
||||
|
||||
func attachNetwork(inst *store.Instance, vmConfig *vz.VirtualMachineConfiguration) error {
|
||||
func attachNetwork(ctx context.Context, inst *store.Instance, vmConfig *vz.VirtualMachineConfiguration) error {
|
||||
var configurations []*vz.VirtioNetworkDeviceConfiguration
|
||||
|
||||
// Configure default usernetwork with limayaml.MACAddress(inst.Dir) for eth0 interface
|
||||
@@ -390,7 +390,7 @@ func attachNetwork(inst *store.Instance, vmConfig *vz.VirtualMachineConfiguratio
|
||||
return err
|
||||
}
|
||||
|
||||
clientFile, err := DialQemu(sock)
|
||||
clientFile, err := DialQemu(ctx, sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -402,7 +402,7 @@ func attachNetwork(inst *store.Instance, vmConfig *vz.VirtualMachineConfiguratio
|
||||
}
|
||||
}
|
||||
} else if nw.Socket != "" {
|
||||
clientFile, err := DialQemu(nw.Socket)
|
||||
clientFile, err := DialQemu(ctx, nw.Socket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -434,7 +434,7 @@ func validateDiskFormat(diskPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func attachDisks(inst *store.Instance, vmConfig *vz.VirtualMachineConfiguration) error {
|
||||
func attachDisks(ctx context.Context, inst *store.Instance, vmConfig *vz.VirtualMachineConfiguration) error {
|
||||
baseDiskPath := filepath.Join(inst.Dir, filenames.BaseDisk)
|
||||
diffDiskPath := filepath.Join(inst.Dir, filenames.DiffDisk)
|
||||
ciDataPath := filepath.Join(inst.Dir, filenames.CIDataISO)
|
||||
@@ -471,7 +471,7 @@ func attachDisks(inst *store.Instance, vmConfig *vz.VirtualMachineConfiguration)
|
||||
}
|
||||
configurations = append(configurations, diffDisk)
|
||||
|
||||
diskUtil := proxyimgutil.NewDiskUtil()
|
||||
diskUtil := proxyimgutil.NewDiskUtil(ctx)
|
||||
|
||||
for _, d := range inst.Config.AdditionalDisks {
|
||||
diskName := d.Name
|
||||
@@ -492,7 +492,7 @@ func attachDisks(inst *store.Instance, vmConfig *vz.VirtualMachineConfiguration)
|
||||
// ConvertToRaw is a NOP if no conversion is needed
|
||||
logrus.Debugf("Converting extra disk %q to a raw disk (if it is not a raw)", extraDiskPath)
|
||||
|
||||
if err = diskUtil.ConvertToRaw(extraDiskPath, extraDiskPath, nil, true); err != nil {
|
||||
if err = diskUtil.ConvertToRaw(ctx, extraDiskPath, extraDiskPath, nil, true); err != nil {
|
||||
return fmt.Errorf("failed to convert extra disk %q to a raw disk: %w", extraDiskPath, err)
|
||||
}
|
||||
extraDiskPathAttachment, err := vz.NewDiskImageStorageDeviceAttachmentWithCacheAndSync(extraDiskPath, false, diskImageCachingMode, vz.DiskImageSynchronizationModeFsync)
|
||||
|
||||
@@ -96,7 +96,7 @@ func (l *LimaVzDriver) Configure(inst *store.Instance) *driver.ConfiguredDriver
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LimaVzDriver) Validate() error {
|
||||
func (l *LimaVzDriver) Validate(_ context.Context) error {
|
||||
macOSProductVersion, err := osutil.ProductVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -77,7 +77,7 @@ func (l *LimaWslDriver) Configure(inst *store.Instance) *driver.ConfiguredDriver
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LimaWslDriver) Validate() error {
|
||||
func (l *LimaWslDriver) Validate(_ context.Context) error {
|
||||
if *l.Instance.Config.MountType != limayaml.WSLMount {
|
||||
return fmt.Errorf("field `mountType` must be %q for WSL2 driver, got %q", limayaml.WSLMount, *l.Instance.Config.MountType)
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func (l *LimaWslDriver) Unregister(ctx context.Context) error {
|
||||
// As of 08-01-2024, github.com/mdlayher/vsock does not natively support vsock on
|
||||
// Windows, so use the winio library to create the connection.
|
||||
func (l *LimaWslDriver) GuestAgentConn(ctx context.Context) (net.Conn, string, error) {
|
||||
VMIDStr, err := windows.GetInstanceVMID(fmt.Sprintf("lima-%s", l.Instance.Name))
|
||||
VMIDStr, err := windows.GetInstanceVMID(ctx, fmt.Sprintf("lima-%s", l.Instance.Name))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@@ -57,8 +57,7 @@ func GenerateEditorWarningHeader() string {
|
||||
// OpenEditor opens an editor, and returns the content (not path) of the modified yaml.
|
||||
//
|
||||
// OpenEditor returns nil when the file was saved as an empty file, optionally with whitespaces.
|
||||
func OpenEditor(content []byte, hdr string) ([]byte, error) {
|
||||
ctx := context.TODO()
|
||||
func OpenEditor(ctx context.Context, content []byte, hdr string) ([]byte, error) {
|
||||
editor := editorcmd.Detect()
|
||||
if editor == "" {
|
||||
return nil, errors.New("could not detect a text editor binary, try setting $EDITOR")
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/lima-vm/lima/v2/pkg/guestagent/timesync"
|
||||
)
|
||||
|
||||
func New(newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration) (Agent, error) {
|
||||
func New(ctx context.Context, newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration) (Agent, error) {
|
||||
a := &agent{
|
||||
newTicker: newTicker,
|
||||
kubernetesServiceWatcher: kubernetesservice.NewServiceWatcher(),
|
||||
@@ -39,7 +39,7 @@ func New(newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration
|
||||
return nil, err
|
||||
}
|
||||
logrus.Infof("Auditing is not available: %s", err)
|
||||
return startGuestAgentRoutines(a, false), nil
|
||||
return startGuestAgentRoutines(ctx, a, false), nil
|
||||
}
|
||||
|
||||
auditStatus, err := auditClient.GetStatus()
|
||||
@@ -50,7 +50,7 @@ func New(newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration
|
||||
return nil, err
|
||||
}
|
||||
logrus.Infof("Auditing is not permitted: %s", err)
|
||||
return startGuestAgentRoutines(a, false), nil
|
||||
return startGuestAgentRoutines(ctx, a, false), nil
|
||||
}
|
||||
|
||||
if auditStatus.Enabled == 0 {
|
||||
@@ -73,7 +73,7 @@ func New(newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration
|
||||
a.worthCheckingIPTables = true
|
||||
}
|
||||
logrus.Infof("Auditing enabled (%d)", auditStatus.Enabled)
|
||||
return startGuestAgentRoutines(a, true), nil
|
||||
return startGuestAgentRoutines(ctx, a, true), nil
|
||||
}
|
||||
|
||||
// startGuestAgentRoutines sets worthCheckingIPTables to true if auditing is not supported,
|
||||
@@ -81,11 +81,11 @@ func New(newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration
|
||||
//
|
||||
// Auditing is not supported in a kernels and is not currently supported outside of the initial namespace, so does not work
|
||||
// from inside a container or WSL2 instance, for example.
|
||||
func startGuestAgentRoutines(a *agent, supportsAuditing bool) *agent {
|
||||
func startGuestAgentRoutines(ctx context.Context, a *agent, supportsAuditing bool) *agent {
|
||||
if !supportsAuditing {
|
||||
a.worthCheckingIPTables = true
|
||||
}
|
||||
go a.kubernetesServiceWatcher.Start()
|
||||
go a.kubernetesServiceWatcher.Start(ctx)
|
||||
go a.fixSystemTimeSkew()
|
||||
|
||||
return a
|
||||
@@ -218,7 +218,7 @@ func (a *agent) Events(ctx context.Context, ch chan *api.Event) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *agent) LocalPorts(_ context.Context) ([]*api.IPPort, error) {
|
||||
func (a *agent) LocalPorts(ctx context.Context) ([]*api.IPPort, error) {
|
||||
var res []*api.IPPort
|
||||
tcpParsed, err := procnettcp.ParseFiles()
|
||||
if err != nil {
|
||||
@@ -257,7 +257,7 @@ func (a *agent) LocalPorts(_ context.Context) ([]*api.IPPort, error) {
|
||||
|
||||
var ipts []iptables.Entry
|
||||
if a.worthCheckingIPTables {
|
||||
ipts, err = iptables.GetPorts()
|
||||
ipts, err = iptables.GetPorts(ctx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ type Entry struct {
|
||||
// -j DNAT this tells us it's the line doing the port forwarding.
|
||||
var findPortRegex = regexp.MustCompile(`-A\s+CNI-DN-\w*\s+(?:-d ((?:\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}))?(?:/32\s+)?-p (tcp)?.*--dport (\d+) -j DNAT`)
|
||||
|
||||
func GetPorts() ([]Entry, error) {
|
||||
func GetPorts(ctx context.Context) ([]Entry, error) {
|
||||
// TODO: add support for ipv6
|
||||
|
||||
// Detect the location of iptables. If it is not installed skip the lookup
|
||||
@@ -63,7 +63,7 @@ func GetPorts() ([]Entry, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return checkPortsOpen(pts)
|
||||
return checkPortsOpen(ctx, pts)
|
||||
}
|
||||
|
||||
func parsePortsFromRules(rules []string) ([]Entry, error) {
|
||||
@@ -127,8 +127,7 @@ func listNATRules(pth string) ([]string, error) {
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func checkPortsOpen(pts []Entry) ([]Entry, error) {
|
||||
ctx := context.TODO()
|
||||
func checkPortsOpen(ctx context.Context, pts []Entry) ([]Entry, error) {
|
||||
var entries []Entry
|
||||
for _, pt := range pts {
|
||||
if pt.TCP {
|
||||
|
||||
@@ -58,11 +58,11 @@ func (s *ServiceWatcher) getServiceInformer() cache.SharedIndexInformer {
|
||||
return s.serviceInformer
|
||||
}
|
||||
|
||||
func (s *ServiceWatcher) Start() {
|
||||
func (s *ServiceWatcher) Start(ctx context.Context) {
|
||||
logrus.Info("Monitoring kubernetes services")
|
||||
const retryInterval = 10 * time.Second
|
||||
const pollImmediately = false
|
||||
_ = wait.PollUntilContextCancel(context.TODO(), retryInterval, pollImmediately, func(ctx context.Context) (done bool, err error) {
|
||||
_ = wait.PollUntilContextCancel(ctx, retryInterval, pollImmediately, func(ctx context.Context) (done bool, err error) {
|
||||
kubeClient, err := tryGetKubeClient()
|
||||
if err != nil {
|
||||
logrus.Tracef("failed to get kube client: %v, will retry in %v", err, retryInterval)
|
||||
|
||||
@@ -142,9 +142,8 @@ func NewHandler(opts HandlerOptions) (dns.Handler, error) {
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *Handler) handleQuery(w dns.ResponseWriter, req *dns.Msg) {
|
||||
func (h *Handler) handleQuery(ctx context.Context, w dns.ResponseWriter, req *dns.Msg) {
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
reply dns.Msg
|
||||
handled bool
|
||||
)
|
||||
@@ -340,7 +339,7 @@ func (h *Handler) handleDefault(w dns.ResponseWriter, req *dns.Msg) {
|
||||
func (h *Handler) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
|
||||
switch req.Opcode {
|
||||
case dns.OpcodeQuery:
|
||||
h.handleQuery(w, req)
|
||||
h.handleQuery(context.Background(), w, req)
|
||||
default:
|
||||
h.handleDefault(w, req)
|
||||
}
|
||||
|
||||
@@ -110,14 +110,14 @@ func WithCloudInitProgress(enabled bool) Opt {
|
||||
// New creates the HostAgent.
|
||||
//
|
||||
// stdout is for emitting JSON lines of Events.
|
||||
func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt) (*HostAgent, error) {
|
||||
func New(ctx context.Context, instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt) (*HostAgent, error) {
|
||||
var o options
|
||||
for _, f := range opts {
|
||||
if err := f(&o); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -159,10 +159,10 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt
|
||||
vSockPort := limaDriver.Info().VsockPort
|
||||
virtioPort := limaDriver.Info().VirtioPort
|
||||
|
||||
if err := cidata.GenerateCloudConfig(inst.Dir, instName, inst.Config); err != nil {
|
||||
if err := cidata.GenerateCloudConfig(ctx, inst.Dir, instName, inst.Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cidata.GenerateISO9660(inst.Dir, instName, inst.Config, udpDNSLocalPort, tcpDNSLocalPort, o.guestAgentBinary, o.nerdctlArchive, vSockPort, virtioPort); err != nil {
|
||||
if err := cidata.GenerateISO9660(ctx, inst.Dir, instName, inst.Config, udpDNSLocalPort, tcpDNSLocalPort, o.guestAgentBinary, o.nerdctlArchive, vSockPort, virtioPort); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt
|
||||
return nil, err
|
||||
}
|
||||
sshOpts, err := sshutil.SSHOpts(
|
||||
ctx,
|
||||
sshExe,
|
||||
inst.Dir,
|
||||
*inst.Config.User.Name,
|
||||
@@ -335,7 +336,7 @@ func (a *HostAgent) Run(ctx context.Context) error {
|
||||
|
||||
// WSL instance SSH address isn't known until after VM start
|
||||
if *a.instConfig.VMType == limayaml.WSL2 {
|
||||
sshAddr, err := store.GetSSHAddress(a.instName)
|
||||
sshAddr, err := store.GetSSHAddress(ctx, a.instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -472,7 +473,7 @@ sudo chown -R "${USER}" /run/host-services`
|
||||
}
|
||||
}
|
||||
if *a.instConfig.MountType == limayaml.REVSSHFS && !*a.instConfig.Plain {
|
||||
mounts, err := a.setupMounts()
|
||||
mounts, err := a.setupMounts(ctx)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package hostagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -20,13 +21,13 @@ type mount struct {
|
||||
close func() error
|
||||
}
|
||||
|
||||
func (a *HostAgent) setupMounts() ([]*mount, error) {
|
||||
func (a *HostAgent) setupMounts(ctx context.Context) ([]*mount, error) {
|
||||
var (
|
||||
res []*mount
|
||||
errs []error
|
||||
)
|
||||
for _, f := range a.instConfig.Mounts {
|
||||
m, err := a.setupMount(f)
|
||||
m, err := a.setupMount(ctx, f)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
@@ -36,7 +37,7 @@ func (a *HostAgent) setupMounts() ([]*mount, error) {
|
||||
return res, errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (a *HostAgent) setupMount(m limayaml.Mount) (*mount, error) {
|
||||
func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, error) {
|
||||
if err := os.MkdirAll(m.Location, 0o755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -53,7 +54,7 @@ func (a *HostAgent) setupMount(m limayaml.Mount) (*mount, error) {
|
||||
resolvedLocation := m.Location
|
||||
if runtime.GOOS == "windows" {
|
||||
var err error
|
||||
resolvedLocation, err = ioutilx.WindowsSubsystemPath(m.Location)
|
||||
resolvedLocation, err = ioutilx.WindowsSubsystemPath(ctx, m.Location)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
package imgutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ImageDiskManager defines the common operations for disk image utilities.
|
||||
type ImageDiskManager interface {
|
||||
// CreateDisk creates a new disk image with the specified size.
|
||||
CreateDisk(disk string, size int64) error
|
||||
CreateDisk(ctx context.Context, disk string, size int64) error
|
||||
|
||||
// ResizeDisk resizes an existing disk image to the specified size.
|
||||
ResizeDisk(disk string, size int64) error
|
||||
ResizeDisk(ctx context.Context, disk string, size int64) error
|
||||
|
||||
// ConvertToRaw converts a disk image to raw format.
|
||||
ConvertToRaw(source, dest string, size *int64, allowSourceWithBackingFile bool) error
|
||||
ConvertToRaw(ctx context.Context, source, dest string, size *int64, allowSourceWithBackingFile bool) error
|
||||
|
||||
// MakeSparse makes a file sparse, starting from the specified offset.
|
||||
MakeSparse(f *os.File, offset int64) error
|
||||
MakeSparse(ctx context.Context, f *os.File, offset int64) error
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
package nativeimgutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -153,7 +154,7 @@ func makeSparse(f *os.File, offset int64) error {
|
||||
}
|
||||
|
||||
// CreateDisk creates a new disk image with the specified size.
|
||||
func (n *NativeImageUtil) CreateDisk(disk string, size int64) error {
|
||||
func (n *NativeImageUtil) CreateDisk(_ context.Context, disk string, size int64) error {
|
||||
if _, err := os.Stat(disk); err == nil || !errors.Is(err, fs.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
@@ -167,17 +168,17 @@ func (n *NativeImageUtil) CreateDisk(disk string, size int64) error {
|
||||
}
|
||||
|
||||
// ConvertToRaw converts a disk image to raw format.
|
||||
func (n *NativeImageUtil) ConvertToRaw(source, dest string, size *int64, allowSourceWithBackingFile bool) error {
|
||||
func (n *NativeImageUtil) ConvertToRaw(_ context.Context, source, dest string, size *int64, allowSourceWithBackingFile bool) error {
|
||||
return convertToRaw(source, dest, size, allowSourceWithBackingFile)
|
||||
}
|
||||
|
||||
// ResizeDisk resizes an existing disk image to the specified size.
|
||||
func (n *NativeImageUtil) ResizeDisk(disk string, size int64) error {
|
||||
func (n *NativeImageUtil) ResizeDisk(_ context.Context, disk string, size int64) error {
|
||||
roundedSize := roundUp(size)
|
||||
return os.Truncate(disk, roundedSize)
|
||||
}
|
||||
|
||||
// MakeSparse makes a file sparse, starting from the specified offset.
|
||||
func (n *NativeImageUtil) MakeSparse(f *os.File, offset int64) error {
|
||||
func (n *NativeImageUtil) MakeSparse(_ context.Context, f *os.File, offset int64) error {
|
||||
return makeSparse(f, offset)
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
package proxyimgutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -20,7 +21,7 @@ type ImageDiskManager struct {
|
||||
}
|
||||
|
||||
// NewDiskUtil returns a new instance of ImageDiskManager that uses both QEMU and native image utilities.
|
||||
func NewDiskUtil() imgutil.ImageDiskManager {
|
||||
func NewDiskUtil(_ context.Context) imgutil.ImageDiskManager {
|
||||
return &ImageDiskManager{
|
||||
qemu: &qemuimgutil.QemuImageUtil{DefaultFormat: qemuimgutil.QemuImgFormat},
|
||||
native: &nativeimgutil.NativeImageUtil{},
|
||||
@@ -28,48 +29,48 @@ func NewDiskUtil() imgutil.ImageDiskManager {
|
||||
}
|
||||
|
||||
// CreateDisk creates a new disk image with the specified size.
|
||||
func (p *ImageDiskManager) CreateDisk(disk string, size int64) error {
|
||||
err := p.qemu.CreateDisk(disk, size)
|
||||
func (p *ImageDiskManager) CreateDisk(ctx context.Context, disk string, size int64) error {
|
||||
err := p.qemu.CreateDisk(ctx, disk, size)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if errors.Is(err, exec.ErrNotFound) {
|
||||
return p.native.CreateDisk(disk, size)
|
||||
return p.native.CreateDisk(ctx, disk, size)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ResizeDisk resizes an existing disk image to the specified size.
|
||||
func (p *ImageDiskManager) ResizeDisk(disk string, size int64) error {
|
||||
err := p.qemu.ResizeDisk(disk, size)
|
||||
func (p *ImageDiskManager) ResizeDisk(ctx context.Context, disk string, size int64) error {
|
||||
err := p.qemu.ResizeDisk(ctx, disk, size)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if errors.Is(err, exec.ErrNotFound) {
|
||||
return p.native.ResizeDisk(disk, size)
|
||||
return p.native.ResizeDisk(ctx, disk, size)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ConvertToRaw converts a disk image to raw format.
|
||||
func (p *ImageDiskManager) ConvertToRaw(source, dest string, size *int64, allowSourceWithBackingFile bool) error {
|
||||
err := p.qemu.ConvertToRaw(source, dest, size, allowSourceWithBackingFile)
|
||||
func (p *ImageDiskManager) ConvertToRaw(ctx context.Context, source, dest string, size *int64, allowSourceWithBackingFile bool) error {
|
||||
err := p.qemu.ConvertToRaw(ctx, source, dest, size, allowSourceWithBackingFile)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if errors.Is(err, exec.ErrNotFound) {
|
||||
return p.native.ConvertToRaw(source, dest, size, allowSourceWithBackingFile)
|
||||
return p.native.ConvertToRaw(ctx, source, dest, size, allowSourceWithBackingFile)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *ImageDiskManager) MakeSparse(f *os.File, offset int64) error {
|
||||
err := p.qemu.MakeSparse(f, offset)
|
||||
func (p *ImageDiskManager) MakeSparse(ctx context.Context, f *os.File, offset int64) error {
|
||||
err := p.qemu.MakeSparse(ctx, f, offset)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if errors.Is(err, exec.ErrNotFound) {
|
||||
return p.native.MakeSparse(f, offset)
|
||||
return p.native.MakeSparse(ctx, f, offset)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"github.com/lima-vm/lima/v2/pkg/store/filenames"
|
||||
)
|
||||
|
||||
func Clone(_ context.Context, oldInst *store.Instance, newInstName string) (*store.Instance, error) {
|
||||
func Clone(ctx context.Context, oldInst *store.Instance, newInstName string) (*store.Instance, error) {
|
||||
if newInstName == "" {
|
||||
return nil, errors.New("got empty instName")
|
||||
}
|
||||
@@ -86,5 +86,5 @@ func Clone(_ context.Context, oldInst *store.Instance, newInstName string) (*sto
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return store.Inspect(newInstName)
|
||||
return store.Inspect(ctx, newInstName)
|
||||
}
|
||||
@@ -43,7 +43,7 @@ func Create(ctx context.Context, instName string, instConfig []byte, saveBrokenY
|
||||
}
|
||||
// limayaml.Load() needs to pass the store file path to limayaml.FillDefault() to calculate default MAC addresses
|
||||
filePath := filepath.Join(instDir, filenames.LimaYAML)
|
||||
loadedInstConfig, err := limayaml.LoadWithWarnings(instConfig, filePath)
|
||||
loadedInstConfig, err := limayaml.LoadWithWarnings(ctx, instConfig, filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,14 +63,14 @@ func Create(ctx context.Context, instName string, instConfig []byte, saveBrokenY
|
||||
if err := os.WriteFile(filePath, instConfig, 0o644); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cidata.GenerateCloudConfig(instDir, instName, loadedInstConfig); err != nil {
|
||||
if err := cidata.GenerateCloudConfig(ctx, instDir, instName, loadedInstConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(instDir, filenames.LimaVersion), []byte(version.Version), 0o444); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inst, err := store.Inspect(instName)
|
||||
inst, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func Prepare(ctx context.Context, inst *store.Instance) (*Prepared, error) {
|
||||
return nil, fmt.Errorf("failed to create driver instance: %w", err)
|
||||
}
|
||||
|
||||
if err := limaDriver.Validate(); err != nil {
|
||||
if err := limaDriver.Validate(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ func Prepare(ctx context.Context, inst *store.Instance) (*Prepared, error) {
|
||||
}
|
||||
|
||||
// Ensure diffDisk size matches the store
|
||||
if err := prepareDiffDisk(inst); err != nil {
|
||||
if err := prepareDiffDisk(ctx, inst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -438,7 +438,7 @@ func ShowMessage(inst *store.Instance) error {
|
||||
|
||||
// prepareDiffDisk checks the disk size difference between inst.Disk and yaml.Disk.
|
||||
// If there is no diffDisk, return nil (the instance has not been initialized or started yet).
|
||||
func prepareDiffDisk(inst *store.Instance) error {
|
||||
func prepareDiffDisk(ctx context.Context, inst *store.Instance) error {
|
||||
diffDisk := filepath.Join(inst.Dir, filenames.DiffDisk)
|
||||
|
||||
// Handle the instance initialization
|
||||
@@ -474,9 +474,9 @@ func prepareDiffDisk(inst *store.Instance) error {
|
||||
return errors.New("diffDisk: Shrinking is currently unavailable")
|
||||
}
|
||||
|
||||
diskUtil := proxyimgutil.NewDiskUtil()
|
||||
diskUtil := proxyimgutil.NewDiskUtil(ctx)
|
||||
|
||||
err = diskUtil.ResizeDisk(diffDisk, inst.Disk)
|
||||
err = diskUtil.ResizeDisk(ctx, diffDisk, inst.Disk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func waitForInstanceShutdown(ctx context.Context, inst *store.Instance) error {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
updatedInst, err := store.Inspect(inst.Name)
|
||||
updatedInst, err := store.Inspect(ctx, inst.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to inspect instance status: %w", err)
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ func FromUTF16leToString(r io.Reader) (string, error) {
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func WindowsSubsystemPath(orig string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func WindowsSubsystemPath(ctx context.Context, orig string) (string, error) {
|
||||
out, err := exec.CommandContext(ctx, "cygpath", filepath.ToSlash(orig)).CombinedOutput()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to convert path to mingw, maybe not using Git ssh?")
|
||||
@@ -60,8 +59,7 @@ func WindowsSubsystemPath(orig string) (string, error) {
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
}
|
||||
|
||||
func WindowsSubsystemPathForLinux(orig, distro string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func WindowsSubsystemPathForLinux(ctx context.Context, orig, distro string) (string, error) {
|
||||
out, err := exec.CommandContext(ctx, "wsl", "-d", distro, "--exec", "wslpath", filepath.ToSlash(orig)).CombinedOutput()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to convert path to mingw, maybe wsl command is not operational?")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package limainfo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/fs"
|
||||
|
||||
@@ -40,12 +41,12 @@ type GuestAgent struct {
|
||||
// New returns a LimaInfo object with the Lima version, a list of all Templates and their location,
|
||||
// the DefaultTemplate corresponding to template://default with all defaults filled in, the
|
||||
// LimaHome location, a list of all supported VMTypes, and a map of GuestAgents for each architecture.
|
||||
func New() (*LimaInfo, error) {
|
||||
func New(ctx context.Context) (*LimaInfo, error) {
|
||||
b, err := templatestore.Read(templatestore.Default)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y, err := limayaml.Load(b, "")
|
||||
y, err := limayaml.Load(ctx, b, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package limayaml
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
_ "embed"
|
||||
"errors"
|
||||
@@ -137,7 +138,7 @@ func defaultGuestInstallPrefix() string {
|
||||
// - Networks are appended in d, y, o order
|
||||
// - DNS are picked from the highest priority where DNS is not empty.
|
||||
// - CACertificates Files and Certs are uniquely appended in d, y, o order
|
||||
func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
|
||||
func FillDefault(ctx context.Context, y, d, o *LimaYAML, filePath string, warn bool) {
|
||||
instDir := filepath.Dir(filePath)
|
||||
|
||||
// existingLimaVersion can be empty if the instance was created with Lima prior to v0.20,
|
||||
@@ -184,22 +185,22 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
|
||||
y.User.UID = o.User.UID
|
||||
}
|
||||
if y.User.Name == nil {
|
||||
y.User.Name = ptr.Of(osutil.LimaUser(existingLimaVersion, warn).Username)
|
||||
y.User.Name = ptr.Of(osutil.LimaUser(ctx, existingLimaVersion, warn).Username)
|
||||
warn = false
|
||||
}
|
||||
if y.User.Comment == nil {
|
||||
y.User.Comment = ptr.Of(osutil.LimaUser(existingLimaVersion, warn).Name)
|
||||
y.User.Comment = ptr.Of(osutil.LimaUser(ctx, existingLimaVersion, warn).Name)
|
||||
warn = false
|
||||
}
|
||||
if y.User.Home == nil {
|
||||
y.User.Home = ptr.Of(osutil.LimaUser(existingLimaVersion, warn).HomeDir)
|
||||
y.User.Home = ptr.Of(osutil.LimaUser(ctx, existingLimaVersion, warn).HomeDir)
|
||||
warn = false
|
||||
}
|
||||
if y.User.Shell == nil {
|
||||
y.User.Shell = ptr.Of("/bin/bash")
|
||||
}
|
||||
if y.User.UID == nil {
|
||||
uidString := osutil.LimaUser(existingLimaVersion, warn).Uid
|
||||
uidString := osutil.LimaUser(ctx, existingLimaVersion, warn).Uid
|
||||
if uid, err := strconv.ParseUint(uidString, 10, 32); err == nil {
|
||||
y.User.UID = ptr.Of(uint32(uid))
|
||||
} else {
|
||||
@@ -778,7 +779,7 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
|
||||
mountLocation := mounts[i].Location
|
||||
if runtime.GOOS == "windows" {
|
||||
var err error
|
||||
mountLocation, err = ioutilx.WindowsSubsystemPath(mountLocation)
|
||||
mountLocation, err = ioutilx.WindowsSubsystemPath(ctx, mountLocation)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warnf("Couldn't convert location %q into mount target", mounts[i].Location)
|
||||
}
|
||||
@@ -1189,7 +1190,7 @@ var hasSMEDarwin = sync.OnceValue(func() bool {
|
||||
return false
|
||||
}
|
||||
// golang.org/x/sys/cpu does not support inspecting the availability of SME yet
|
||||
s, err := osutil.Sysctl("hw.optional.arm.FEAT_SME")
|
||||
s, err := osutil.Sysctl(context.Background(), "hw.optional.arm.FEAT_SME")
|
||||
if err != nil {
|
||||
logrus.WithError(err).Debug("failed to check hw.optional.arm.FEAT_SME")
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func TestFillDefault(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
limaHome, err := dirnames.LimaDir()
|
||||
assert.NilError(t, err)
|
||||
user := osutil.LimaUser("0.0.0", false)
|
||||
user := osutil.LimaUser(t.Context(), "0.0.0", false)
|
||||
user.HomeDir = fmt.Sprintf("/home/%s.linux", user.Username)
|
||||
uid, err := strconv.ParseUint(user.Uid, 10, 32)
|
||||
assert.NilError(t, err)
|
||||
@@ -226,7 +226,7 @@ func TestFillDefault(t *testing.T) {
|
||||
expect.Mounts = slices.Clone(y.Mounts)
|
||||
expect.Mounts[0].MountPoint = ptr.Of(expect.Mounts[0].Location)
|
||||
if runtime.GOOS == "windows" {
|
||||
mountLocation, err := ioutilx.WindowsSubsystemPath(expect.Mounts[0].Location)
|
||||
mountLocation, err := ioutilx.WindowsSubsystemPath(t.Context(), expect.Mounts[0].Location)
|
||||
if err == nil {
|
||||
expect.Mounts[0].MountPoint = ptr.Of(mountLocation)
|
||||
}
|
||||
@@ -322,7 +322,7 @@ func TestFillDefault(t *testing.T) {
|
||||
|
||||
expect.NestedVirtualization = ptr.Of(false)
|
||||
|
||||
FillDefault(&y, &LimaYAML{}, &LimaYAML{}, filePath, false)
|
||||
FillDefault(t.Context(), &y, &LimaYAML{}, &LimaYAML{}, filePath, false)
|
||||
assert.DeepEqual(t, &y, &expect, opts...)
|
||||
|
||||
filledDefaults := y
|
||||
@@ -464,7 +464,7 @@ func TestFillDefault(t *testing.T) {
|
||||
expect.Mounts = slices.Clone(d.Mounts)
|
||||
expect.Mounts[0].MountPoint = ptr.Of(expect.Mounts[0].Location)
|
||||
if runtime.GOOS == "windows" {
|
||||
mountLocation, err := ioutilx.WindowsSubsystemPath(expect.Mounts[0].Location)
|
||||
mountLocation, err := ioutilx.WindowsSubsystemPath(t.Context(), expect.Mounts[0].Location)
|
||||
if err == nil {
|
||||
expect.Mounts[0].MountPoint = ptr.Of(mountLocation)
|
||||
}
|
||||
@@ -501,7 +501,7 @@ func TestFillDefault(t *testing.T) {
|
||||
expect.Plain = ptr.Of(false)
|
||||
|
||||
y = LimaYAML{}
|
||||
FillDefault(&y, &d, &LimaYAML{}, filePath, false)
|
||||
FillDefault(t.Context(), &y, &d, &LimaYAML{}, filePath, false)
|
||||
assert.DeepEqual(t, &y, &expect, opts...)
|
||||
|
||||
dExpect := expect
|
||||
@@ -540,7 +540,7 @@ func TestFillDefault(t *testing.T) {
|
||||
|
||||
t.Logf("d.vmType=%q, y.vmType=%q, expect.vmType=%q", *d.VMType, *y.VMType, *expect.VMType)
|
||||
|
||||
FillDefault(&y, &d, &LimaYAML{}, filePath, false)
|
||||
FillDefault(t.Context(), &y, &d, &LimaYAML{}, filePath, false)
|
||||
assert.DeepEqual(t, &y, &expect, opts...)
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
@@ -737,7 +737,7 @@ func TestFillDefault(t *testing.T) {
|
||||
|
||||
expect.NestedVirtualization = ptr.Of(false)
|
||||
|
||||
FillDefault(&y, &d, &o, filePath, false)
|
||||
FillDefault(t.Context(), &y, &d, &o, filePath, false)
|
||||
assert.DeepEqual(t, &y, &expect, opts...)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package limayaml
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -18,18 +19,18 @@ import (
|
||||
// Load loads the yaml and fulfills unspecified fields with the default values.
|
||||
//
|
||||
// Load does not validate. Use Validate for validation.
|
||||
func Load(b []byte, filePath string) (*LimaYAML, error) {
|
||||
return load(b, filePath, false)
|
||||
func Load(ctx context.Context, b []byte, filePath string) (*LimaYAML, error) {
|
||||
return load(ctx, b, filePath, false)
|
||||
}
|
||||
|
||||
// LoadWithWarnings will call FillDefaults with warnings enabled (e.g. when
|
||||
// the username is not valid on Linux and must be replaced by "Lima").
|
||||
// It is called when creating or editing an instance.
|
||||
func LoadWithWarnings(b []byte, filePath string) (*LimaYAML, error) {
|
||||
return load(b, filePath, true)
|
||||
func LoadWithWarnings(ctx context.Context, b []byte, filePath string) (*LimaYAML, error) {
|
||||
return load(ctx, b, filePath, true)
|
||||
}
|
||||
|
||||
func load(b []byte, filePath string, warn bool) (*LimaYAML, error) {
|
||||
func load(ctx context.Context, b []byte, filePath string, warn bool) (*LimaYAML, error) {
|
||||
var y, d, o LimaYAML
|
||||
|
||||
if err := Unmarshal(b, &y, fmt.Sprintf("main file %q", filePath)); err != nil {
|
||||
@@ -67,6 +68,6 @@ func load(b []byte, filePath string, warn bool) (*LimaYAML, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
FillDefault(&y, &d, &o, filePath, warn)
|
||||
FillDefault(ctx, &y, &d, &o, filePath, warn)
|
||||
return &y, nil
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func TestLoadEmpty(t *testing.T) {
|
||||
_, err := Load([]byte{}, "empty.yaml")
|
||||
_, err := Load(t.Context(), []byte{}, "empty.yaml")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ provision:
|
||||
#!/bin/sh
|
||||
echo three
|
||||
`
|
||||
_, err := Load([]byte(s), "error.yaml")
|
||||
_, err := Load(t.Context(), []byte(s), "error.yaml")
|
||||
assert.ErrorContains(t, err, "map key-value is pre-defined")
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestLoadDiskString(t *testing.T) {
|
||||
additionalDisks:
|
||||
- name
|
||||
`
|
||||
y, err := Load([]byte(s), "disk.yaml")
|
||||
y, err := Load(t.Context(), []byte(s), "disk.yaml")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(y.AdditionalDisks), 1)
|
||||
assert.Equal(t, y.AdditionalDisks[0].Name, "name")
|
||||
@@ -56,7 +56,7 @@ additionalDisks:
|
||||
fsType: "xfs"
|
||||
fsArgs: ["-i","size=512"]
|
||||
`
|
||||
y, err := Load([]byte(s), "disk.yaml")
|
||||
y, err := Load(t.Context(), []byte(s), "disk.yaml")
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, len(y.AdditionalDisks) == 1)
|
||||
assert.Equal(t, y.AdditionalDisks[0].Name, "name")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package limayaml
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -602,11 +603,11 @@ func warnExperimental(y *LimaYAML) {
|
||||
|
||||
// ValidateAgainstLatestConfig validates the values between the latest YAML and the updated(New) YAML.
|
||||
// This validates configuration rules that disallow certain changes, such as shrinking the disk.
|
||||
func ValidateAgainstLatestConfig(yNew, yLatest []byte) error {
|
||||
func ValidateAgainstLatestConfig(ctx context.Context, yNew, yLatest []byte) error {
|
||||
var n LimaYAML
|
||||
|
||||
// Load the latest YAML and fill in defaults
|
||||
l, err := LoadWithWarnings(yLatest, "")
|
||||
l, err := LoadWithWarnings(ctx, yLatest, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func TestValidateEmpty(t *testing.T) {
|
||||
y, err := Load([]byte{}, "empty.yaml")
|
||||
y, err := Load(t.Context(), []byte{}, "empty.yaml")
|
||||
assert.NilError(t, err)
|
||||
err = Validate(y, false)
|
||||
assert.Error(t, err, "field `images` must be set")
|
||||
@@ -60,7 +60,7 @@ func TestValidateMinimumLimaVersion(t *testing.T) {
|
||||
version.Version = tt.currentVersion
|
||||
t.Cleanup(func() { version.Version = oldVersion })
|
||||
|
||||
y, err := Load([]byte("minimumLimaVersion: "+tt.minimumLimaVersion+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte("minimumLimaVersion: "+tt.minimumLimaVersion+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -76,13 +76,13 @@ func TestValidateMinimumLimaVersion(t *testing.T) {
|
||||
func TestValidateDigest(t *testing.T) {
|
||||
images := `images: [{"location": "https://cloud-images.ubuntu.com/releases/oracular/release-20250701/ubuntu-24.10-server-cloudimg-amd64.img",digest: "69f31d3208895e5f646e345fbc95190e5e311ecd1359a4d6ee2c0b6483ceca03"}]`
|
||||
validProbe := `probes: [{"script": "#!foo"}]`
|
||||
y, err := Load([]byte(validProbe+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(validProbe+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
err = Validate(y, false)
|
||||
assert.Error(t, err, "field `images[0].digest` is invalid: 69f31d3208895e5f646e345fbc95190e5e311ecd1359a4d6ee2c0b6483ceca03: invalid checksum digest format")
|
||||
|
||||
images2 := `images: [{"location": "https://cloud-images.ubuntu.com/releases/oracular/release-20250701/ubuntu-24.10-server-cloudimg-amd64.img",digest: "sha001:69f31d3208895e5f646e345fbc95190e5e311ecd1359a4d6ee2c0b6483ceca03"}]`
|
||||
y2, err := Load([]byte(validProbe+"\n"+images2), "lima.yaml")
|
||||
y2, err := Load(t.Context(), []byte(validProbe+"\n"+images2), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
err = Validate(y2, false)
|
||||
assert.Error(t, err, "field `images[0].digest` is invalid: sha001:69f31d3208895e5f646e345fbc95190e5e311ecd1359a4d6ee2c0b6483ceca03: unsupported digest algorithm")
|
||||
@@ -91,21 +91,21 @@ func TestValidateDigest(t *testing.T) {
|
||||
func TestValidateProbes(t *testing.T) {
|
||||
images := `images: [{"location": "/"}]`
|
||||
validProbe := `probes: [{"script": "#!foo"}]`
|
||||
y, err := Load([]byte(validProbe+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(validProbe+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
invalidProbe := `probes: [{"script": "foo"}]`
|
||||
y, err = Load([]byte(invalidProbe+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(invalidProbe+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.Error(t, err, "field `probe[0].script` must start with a '#!' line")
|
||||
|
||||
invalidProbe = `probes: [{file: {digest: decafbad}}]`
|
||||
y, err = Load([]byte(invalidProbe+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(invalidProbe+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -116,28 +116,28 @@ func TestValidateProbes(t *testing.T) {
|
||||
func TestValidateProvisionMode(t *testing.T) {
|
||||
images := `images: [{location: /}]`
|
||||
provisionBoot := `provision: [{mode: boot, script: "touch /tmp/param-$PARAM_BOOT"}]`
|
||||
y, err := Load([]byte(provisionBoot+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(provisionBoot+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
provisionUser := `provision: [{mode: user, script: "touch /tmp/param-$PARAM_USER"}]`
|
||||
y, err = Load([]byte(provisionUser+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(provisionUser+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
provisionDependency := `provision: [{mode: ansible, script: "touch /tmp/param-$PARAM_DEPENDENCY"}]`
|
||||
y, err = Load([]byte(provisionDependency+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(provisionDependency+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
provisionInvalid := `provision: [{mode: invalid}]`
|
||||
y, err = Load([]byte(provisionInvalid+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(provisionInvalid+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -148,21 +148,21 @@ func TestValidateProvisionMode(t *testing.T) {
|
||||
func TestValidateProvisionData(t *testing.T) {
|
||||
images := `images: [{location: /}]`
|
||||
validData := `provision: [{mode: data, path: /tmp, content: hello}]`
|
||||
y, err := Load([]byte(validData+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(validData+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
invalidData := `provision: [{mode: data, content: hello}]`
|
||||
y, err = Load([]byte(invalidData+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(invalidData+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
assert.Error(t, err, "field `provision[0].path` must not be empty when mode is \"data\"")
|
||||
|
||||
invalidData = `provision: [{mode: data, path: /tmp, content: hello, permissions: 9}]`
|
||||
y, err = Load([]byte(invalidData+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(invalidData+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -177,7 +177,7 @@ additionalDisks:
|
||||
- name: "disk1"
|
||||
- name: "disk2"
|
||||
`
|
||||
y, err := Load([]byte(validDisks+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(validDisks+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -187,7 +187,7 @@ additionalDisks:
|
||||
additionalDisks:
|
||||
- name: ""
|
||||
`
|
||||
y, err = Load([]byte(invalidDisks+"\n"+images), "lima.yaml")
|
||||
y, err = Load(t.Context(), []byte(invalidDisks+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -203,7 +203,7 @@ func TestValidateParamName(t *testing.T) {
|
||||
`param: {"Name_123": "value"}`,
|
||||
}
|
||||
for _, param := range validParam {
|
||||
y, err := Load([]byte(param+"\n"+validProvision+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(param+"\n"+validProvision+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -217,7 +217,7 @@ func TestValidateParamName(t *testing.T) {
|
||||
`param: {"Last.Name": "value"}`,
|
||||
}
|
||||
for _, param := range invalidParam {
|
||||
y, err := Load([]byte(param+"\n"+invalidProvision+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(param+"\n"+invalidProvision+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -235,7 +235,7 @@ func TestValidateParamValue(t *testing.T) {
|
||||
`param: {"name": "Symbols ½ and emoji → 👀"}`,
|
||||
}
|
||||
for _, param := range validParam {
|
||||
y, err := Load([]byte(param+"\n"+provision+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(param+"\n"+provision+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -247,7 +247,7 @@ func TestValidateParamValue(t *testing.T) {
|
||||
`param: {"name": "\r"}`,
|
||||
}
|
||||
for _, param := range invalidParam {
|
||||
y, err := Load([]byte(param+"\n"+provision+"\n"+images), "lima.yaml")
|
||||
y, err := Load(t.Context(), []byte(param+"\n"+provision+"\n"+images), "lima.yaml")
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = Validate(y, false)
|
||||
@@ -258,7 +258,7 @@ func TestValidateParamValue(t *testing.T) {
|
||||
func TestValidateParamIsUsed(t *testing.T) {
|
||||
paramYaml := `param:
|
||||
name: value`
|
||||
_, err := Load([]byte(paramYaml), "paramIsNotUsed.yaml")
|
||||
_, err := Load(t.Context(), []byte(paramYaml), "paramIsNotUsed.yaml")
|
||||
assert.Error(t, err, "field `param` key \"name\" is not used in any provision, probe, copyToHost, or portForward")
|
||||
|
||||
fieldsUsingParam := []string{
|
||||
@@ -274,7 +274,7 @@ func TestValidateParamIsUsed(t *testing.T) {
|
||||
`portForwards: [{"guestSocket": "/tmp", "hostSocket": "/tmp/{{ .Param.name }}"}]`,
|
||||
}
|
||||
for _, fieldUsingParam := range fieldsUsingParam {
|
||||
_, err = Load([]byte(fieldUsingParam+"\n"+paramYaml), "paramIsUsed.yaml")
|
||||
_, err = Load(t.Context(), []byte(fieldUsingParam+"\n"+paramYaml), "paramIsUsed.yaml")
|
||||
//
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
@@ -293,7 +293,7 @@ func TestValidateParamIsUsed(t *testing.T) {
|
||||
`portForwards: [{"guestSocket": "/var/run/docker.sock", "hostSocket": "{{.Dir}}/sock/docker-{{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}.sock"}]`,
|
||||
}
|
||||
for _, fieldUsingIfParamRootfulTrue := range fieldsUsingIfParamRootfulTrue {
|
||||
_, err = Load([]byte(fieldUsingIfParamRootfulTrue+"\n"+rootfulYaml), "paramIsUsed.yaml")
|
||||
_, err = Load(t.Context(), []byte(fieldUsingIfParamRootfulTrue+"\n"+rootfulYaml), "paramIsUsed.yaml")
|
||||
//
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
@@ -302,7 +302,7 @@ func TestValidateParamIsUsed(t *testing.T) {
|
||||
rootFulYaml := `param:
|
||||
rootFul: true`
|
||||
for _, fieldUsingIfParamRootfulTrue := range fieldsUsingIfParamRootfulTrue {
|
||||
_, err = Load([]byte(fieldUsingIfParamRootfulTrue+"\n"+rootFulYaml), "paramIsUsed.yaml")
|
||||
_, err = Load(t.Context(), []byte(fieldUsingIfParamRootfulTrue+"\n"+rootFulYaml), "paramIsUsed.yaml")
|
||||
//
|
||||
assert.Error(t, err, "field `param` key \"rootFul\" is not used in any provision, probe, copyToHost, or portForward")
|
||||
}
|
||||
@@ -325,7 +325,7 @@ provision:
|
||||
content: test
|
||||
`
|
||||
|
||||
y, err := Load([]byte(yamlWithMultipleErrors), "multiple-errors.yaml")
|
||||
y, err := Load(t.Context(), []byte(yamlWithMultipleErrors), "multiple-errors.yaml")
|
||||
assert.NilError(t, err)
|
||||
err = Validate(y, false)
|
||||
|
||||
@@ -379,7 +379,7 @@ func TestValidateAgainstLatestConfig(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateAgainstLatestConfig([]byte(tt.yNew), []byte(tt.yLatest))
|
||||
err := ValidateAgainstLatestConfig(t.Context(), []byte(tt.yNew), []byte(tt.yLatest))
|
||||
if tt.wantErr == nil {
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
|
||||
@@ -34,7 +34,7 @@ func Reconcile(ctx context.Context, newInst string) error {
|
||||
}
|
||||
activeNetwork := make(map[string]bool, 3)
|
||||
for _, instName := range instances {
|
||||
instance, err := store.Inspect(instName)
|
||||
instance, err := store.Inspect(ctx, instName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -67,8 +67,7 @@ func Reconcile(ctx context.Context, newInst string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func sudo(user, group, command string) error {
|
||||
ctx := context.TODO()
|
||||
func sudo(ctx context.Context, user, group, command string) error {
|
||||
args := []string{"--user", user, "--group", group, "--non-interactive"}
|
||||
args = append(args, strings.Split(command, " ")...)
|
||||
var stdout, stderr bytes.Buffer
|
||||
@@ -83,8 +82,8 @@ func sudo(user, group, command string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeVarRun(cfg *networks.Config) error {
|
||||
err := sudo("root", "wheel", cfg.MkdirCmd())
|
||||
func makeVarRun(ctx context.Context, cfg *networks.Config) error {
|
||||
err := sudo(ctx, "root", "wheel", cfg.MkdirCmd())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -113,7 +112,7 @@ func makeVarRun(cfg *networks.Config) error {
|
||||
}
|
||||
|
||||
func startDaemon(ctx context.Context, cfg *networks.Config, name, daemon string) error {
|
||||
if err := makeVarRun(cfg); err != nil {
|
||||
if err := makeVarRun(ctx, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
networksDir, err := dirnames.LimaNetworksDir()
|
||||
@@ -165,12 +164,12 @@ var validation struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func validateConfig(cfg *networks.Config) error {
|
||||
func validateConfig(ctx context.Context, cfg *networks.Config) error {
|
||||
validation.Do(func() {
|
||||
// make sure all cfg.Paths.* are secure
|
||||
validation.err = cfg.Validate()
|
||||
if validation.err == nil {
|
||||
validation.err = cfg.VerifySudoAccess(cfg.Paths.Sudoers)
|
||||
validation.err = cfg.VerifySudoAccess(ctx, cfg.Paths.Sudoers)
|
||||
}
|
||||
})
|
||||
return validation.err
|
||||
@@ -195,7 +194,7 @@ func startNetwork(ctx context.Context, cfg *networks.Config, name string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := validateConfig(cfg); err != nil {
|
||||
if err := validateConfig(ctx, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
var daemons []string
|
||||
@@ -247,14 +246,14 @@ func stopNetwork(ctx context.Context, cfg *networks.Config, name string) error {
|
||||
pid, _ := store.ReadPIDFile(cfg.PIDFile(name, daemon))
|
||||
if pid != 0 {
|
||||
logrus.Infof("Stopping %s daemon for %q network", daemon, name)
|
||||
if err := validateConfig(cfg); err != nil {
|
||||
if err := validateConfig(ctx, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
user, err := cfg.User(daemon)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sudo(user.User, user.Group, cfg.StopCmd(name, daemon))
|
||||
err = sudo(ctx, user.User, user.Group, cfg.StopCmd(name, daemon))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -57,8 +57,7 @@ func Sudoers() (string, error) {
|
||||
return sb.String(), nil
|
||||
}
|
||||
|
||||
func (c *Config) passwordLessSudo() error {
|
||||
ctx := context.TODO()
|
||||
func (c *Config) passwordLessSudo(ctx context.Context) error {
|
||||
// Flush cached sudo password
|
||||
cmd := exec.CommandContext(ctx, "sudo", "-k")
|
||||
if err := cmd.Run(); err != nil {
|
||||
@@ -84,9 +83,9 @@ func (c *Config) passwordLessSudo() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) VerifySudoAccess(sudoersFile string) error {
|
||||
func (c *Config) VerifySudoAccess(ctx context.Context, sudoersFile string) error {
|
||||
if sudoersFile == "" {
|
||||
err := c.passwordLessSudo()
|
||||
err := c.passwordLessSudo(ctx)
|
||||
if err == nil {
|
||||
logrus.Debug("sudo doesn't seem to require a password")
|
||||
return nil
|
||||
@@ -100,7 +99,7 @@ func (c *Config) VerifySudoAccess(sudoersFile string) error {
|
||||
// Default networks.yaml specifies /etc/sudoers.d/lima file. Don't throw an error when the
|
||||
// file doesn't exist, as long as password-less sudo still works.
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
err = c.passwordLessSudo()
|
||||
err = c.passwordLessSudo(ctx)
|
||||
if err == nil {
|
||||
logrus.Debugf("%q does not exist, but sudo doesn't seem to require a password", sudoersFile)
|
||||
return nil
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
var MachineID = sync.OnceValue(func() string {
|
||||
x, err := machineID()
|
||||
x, err := machineID(context.Background())
|
||||
if err == nil && x != "" {
|
||||
return x
|
||||
}
|
||||
@@ -31,8 +31,7 @@ var MachineID = sync.OnceValue(func() string {
|
||||
return hostname
|
||||
})
|
||||
|
||||
func machineID() (string, error) {
|
||||
ctx := context.TODO()
|
||||
func machineID(ctx context.Context) (string, error) {
|
||||
if runtime.GOOS == "darwin" {
|
||||
ioPlatformExpertDeviceCmd := exec.CommandContext(ctx, "/usr/sbin/ioreg", "-a", "-d2", "-c", "IOPlatformExpertDevice")
|
||||
ioPlatformExpertDevice, err := ioPlatformExpertDeviceCmd.CombinedOutput()
|
||||
|
||||
@@ -25,8 +25,7 @@ func SignalName(sig os.Signal) string {
|
||||
return unix.SignalName(sig.(syscall.Signal))
|
||||
}
|
||||
|
||||
func Sysctl(name string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func Sysctl(ctx context.Context, name string) (string, error) {
|
||||
var stderrBuf bytes.Buffer
|
||||
cmd := exec.CommandContext(ctx, "sysctl", "-n", name)
|
||||
cmd.Stderr = &stderrBuf
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package osutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
@@ -53,6 +54,6 @@ func SignalName(sig os.Signal) string {
|
||||
}
|
||||
}
|
||||
|
||||
func Sysctl(_ string) (string, error) {
|
||||
func Sysctl(_ context.Context, _ string) (string, error) {
|
||||
return "", errors.New("sysctl: unimplemented on Windows")
|
||||
}
|
||||
+4
-5
@@ -102,7 +102,7 @@ var (
|
||||
warnings []string
|
||||
)
|
||||
|
||||
func LimaUser(limaVersion string, warn bool) *user.User {
|
||||
func LimaUser(ctx context.Context, limaVersion string, warn bool) *user.User {
|
||||
once.Do(func() {
|
||||
limaUser = currentUser
|
||||
if !regexUsername.MatchString(limaUser.Username) {
|
||||
@@ -113,7 +113,7 @@ func LimaUser(limaVersion string, warn bool) *user.User {
|
||||
}
|
||||
limaUser.HomeDir = "/home/{{.User}}.linux"
|
||||
if runtime.GOOS == "windows" {
|
||||
idu, err := call([]string{"id", "-u"})
|
||||
idu, err := call(ctx, []string{"id", "-u"})
|
||||
if err != nil {
|
||||
logrus.Debug(err)
|
||||
}
|
||||
@@ -127,7 +127,7 @@ func LimaUser(limaVersion string, warn bool) *user.User {
|
||||
warnings = append(warnings, warning)
|
||||
limaUser.Uid = formatUidGid(uid)
|
||||
}
|
||||
idg, err := call([]string{"id", "-g"})
|
||||
idg, err := call(ctx, []string{"id", "-g"})
|
||||
if err != nil {
|
||||
logrus.Debug(err)
|
||||
}
|
||||
@@ -161,8 +161,7 @@ func LimaUser(limaVersion string, warn bool) *user.User {
|
||||
return &u
|
||||
}
|
||||
|
||||
func call(args []string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func call(ctx context.Context, args []string) (string, error) {
|
||||
cmd := exec.CommandContext(ctx, args[0], args[1:]...)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
||||
@@ -18,7 +18,7 @@ const limaVersion = "1.0.0"
|
||||
func TestLimaUserAdminNew(t *testing.T) {
|
||||
currentUser.Username = "admin"
|
||||
once = new(sync.Once)
|
||||
user := LimaUser(limaVersion, false)
|
||||
user := LimaUser(t.Context(), limaVersion, false)
|
||||
assert.Equal(t, user.Username, fallbackUser)
|
||||
}
|
||||
|
||||
@@ -26,21 +26,21 @@ func TestLimaUserAdminNew(t *testing.T) {
|
||||
func TestLimaUserAdminOld(t *testing.T) {
|
||||
currentUser.Username = "admin"
|
||||
once = new(sync.Once)
|
||||
user := LimaUser("0.23.0", false)
|
||||
user := LimaUser(t.Context(), "0.23.0", false)
|
||||
assert.Equal(t, user.Username, "admin")
|
||||
}
|
||||
|
||||
func TestLimaUserInvalid(t *testing.T) {
|
||||
currentUser.Username = "use@example.com"
|
||||
once = new(sync.Once)
|
||||
user := LimaUser(limaVersion, false)
|
||||
user := LimaUser(t.Context(), limaVersion, false)
|
||||
assert.Equal(t, user.Username, fallbackUser)
|
||||
}
|
||||
|
||||
func TestLimaUserUid(t *testing.T) {
|
||||
currentUser.Username = fallbackUser
|
||||
once = new(sync.Once)
|
||||
user := LimaUser(limaVersion, false)
|
||||
user := LimaUser(t.Context(), limaVersion, false)
|
||||
_, err := strconv.Atoi(user.Uid)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ func TestLimaUserUid(t *testing.T) {
|
||||
func TestLimaUserGid(t *testing.T) {
|
||||
currentUser.Username = fallbackUser
|
||||
once = new(sync.Once)
|
||||
user := LimaUser(limaVersion, false)
|
||||
user := LimaUser(t.Context(), limaVersion, false)
|
||||
_, err := strconv.Atoi(user.Gid)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func TestLimaUserGid(t *testing.T) {
|
||||
func TestLimaHomeDir(t *testing.T) {
|
||||
currentUser.Username = fallbackUser
|
||||
once = new(sync.Once)
|
||||
user := LimaUser(limaVersion, false)
|
||||
user := LimaUser(t.Context(), limaVersion, false)
|
||||
// check for absolute unix path (/home)
|
||||
assert.Assert(t, path.IsAbs(user.HomeDir), user.HomeDir)
|
||||
}
|
||||
@@ -49,8 +49,7 @@ type InfoFormatSpecific struct {
|
||||
Data json.RawMessage `json:"data,omitempty"` // since QEMU 1.7
|
||||
}
|
||||
|
||||
func resizeDisk(disk, format string, size int64) error {
|
||||
ctx := context.TODO()
|
||||
func resizeDisk(ctx context.Context, disk, format string, size int64) error {
|
||||
args := []string{"resize", "-f", format, disk, strconv.FormatInt(size, 10)}
|
||||
cmd := exec.CommandContext(ctx, "qemu-img", args...)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
@@ -104,14 +103,14 @@ type InfoFormatSpecificDataVmdkExtent struct {
|
||||
ClusterSize int `json:"cluster-size,omitempty"` // since QEMU 1.7
|
||||
}
|
||||
|
||||
func convertToRaw(source, dest string) error {
|
||||
func convertToRaw(ctx context.Context, source, dest string) error {
|
||||
if source != dest {
|
||||
return execQemuImgConvert(source, dest)
|
||||
return execQemuImgConvert(ctx, source, dest)
|
||||
}
|
||||
|
||||
// If source == dest, we need to use a temporary file to avoid file locking issues
|
||||
|
||||
info, err := getInfo(source)
|
||||
info, err := getInfo(ctx, source)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get info for source disk %q: %w", source, err)
|
||||
}
|
||||
@@ -122,15 +121,14 @@ func convertToRaw(source, dest string) error {
|
||||
tempFile := dest + ".lima-qemu-convert.tmp"
|
||||
defer os.Remove(tempFile)
|
||||
|
||||
if err := execQemuImgConvert(source, tempFile); err != nil {
|
||||
if err := execQemuImgConvert(ctx, source, tempFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Rename(tempFile, dest)
|
||||
}
|
||||
|
||||
func execQemuImgConvert(source, dest string) error {
|
||||
ctx := context.TODO()
|
||||
func execQemuImgConvert(ctx context.Context, source, dest string) error {
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd := exec.CommandContext(ctx, "qemu-img", "convert", "-O", "raw", source, dest)
|
||||
cmd.Stdout = &stdout
|
||||
@@ -150,8 +148,7 @@ func parseInfo(b []byte) (*Info, error) {
|
||||
return &imgInfo, nil
|
||||
}
|
||||
|
||||
func getInfo(f string) (*Info, error) {
|
||||
ctx := context.TODO()
|
||||
func getInfo(ctx context.Context, f string) (*Info, error) {
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd := exec.CommandContext(ctx, "qemu-img", "info", "--output=json", "--force-share", f)
|
||||
cmd.Stdout = &stdout
|
||||
@@ -164,8 +161,7 @@ func getInfo(f string) (*Info, error) {
|
||||
}
|
||||
|
||||
// CreateDisk creates a new disk image with the specified size.
|
||||
func (q *QemuImageUtil) CreateDisk(disk string, size int64) error {
|
||||
ctx := context.TODO()
|
||||
func (q *QemuImageUtil) CreateDisk(ctx context.Context, disk string, size int64) error {
|
||||
if _, err := os.Stat(disk); err == nil || !errors.Is(err, fs.ErrNotExist) {
|
||||
// disk already exists
|
||||
return err
|
||||
@@ -180,22 +176,22 @@ func (q *QemuImageUtil) CreateDisk(disk string, size int64) error {
|
||||
}
|
||||
|
||||
// ResizeDisk resizes an existing disk image to the specified size.
|
||||
func (q *QemuImageUtil) ResizeDisk(disk string, size int64) error {
|
||||
info, err := getInfo(disk)
|
||||
func (q *QemuImageUtil) ResizeDisk(ctx context.Context, disk string, size int64) error {
|
||||
info, err := getInfo(ctx, disk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get info for disk %q: %w", disk, err)
|
||||
}
|
||||
return resizeDisk(disk, info.Format, size)
|
||||
return resizeDisk(ctx, disk, info.Format, size)
|
||||
}
|
||||
|
||||
// MakeSparse is a stub implementation as the qemu package doesn't provide this functionality.
|
||||
func (q *QemuImageUtil) MakeSparse(_ *os.File, _ int64) error {
|
||||
func (q *QemuImageUtil) MakeSparse(_ context.Context, _ *os.File, _ int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetInfo retrieves the information of a disk image.
|
||||
func GetInfo(path string) (*Info, error) {
|
||||
qemuInfo, err := getInfo(path)
|
||||
func GetInfo(ctx context.Context, path string) (*Info, error) {
|
||||
qemuInfo, err := getInfo(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -204,9 +200,9 @@ func GetInfo(path string) (*Info, error) {
|
||||
}
|
||||
|
||||
// ConvertToRaw converts a disk image to raw format.
|
||||
func (q *QemuImageUtil) ConvertToRaw(source, dest string, size *int64, allowSourceWithBackingFile bool) error {
|
||||
func (q *QemuImageUtil) ConvertToRaw(ctx context.Context, source, dest string, size *int64, allowSourceWithBackingFile bool) error {
|
||||
if !allowSourceWithBackingFile {
|
||||
info, err := getInfo(source)
|
||||
info, err := getInfo(ctx, source)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get info for source disk %q: %w", source, err)
|
||||
}
|
||||
@@ -215,18 +211,18 @@ func (q *QemuImageUtil) ConvertToRaw(source, dest string, size *int64, allowSour
|
||||
}
|
||||
}
|
||||
|
||||
if err := convertToRaw(source, dest); err != nil {
|
||||
if err := convertToRaw(ctx, source, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if size != nil {
|
||||
destInfo, err := getInfo(dest)
|
||||
destInfo, err := getInfo(ctx, dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get info for converted disk %q: %w", dest, err)
|
||||
}
|
||||
|
||||
if *size > destInfo.VSize {
|
||||
return resizeDisk(dest, "raw", *size)
|
||||
return resizeDisk(ctx, dest, "raw", *size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ func newMockDriver(name string) *mockDriver {
|
||||
|
||||
var _ driver.Driver = (*mockDriver)(nil)
|
||||
|
||||
func (m *mockDriver) Validate() error { return nil }
|
||||
func (m *mockDriver) Validate(_ context.Context) error { return nil }
|
||||
func (m *mockDriver) Initialize(_ context.Context) error { return nil }
|
||||
func (m *mockDriver) CreateDisk(_ context.Context) error { return nil }
|
||||
func (m *mockDriver) Start(_ context.Context) (chan error, error) { return nil, nil }
|
||||
|
||||
+14
-16
@@ -91,8 +91,7 @@ func readPublicKey(f string) (PubKey, error) {
|
||||
//
|
||||
// When loadDotSSH is true, ~/.ssh/*.pub will be appended to make the VM accessible without specifying
|
||||
// an identity explicitly.
|
||||
func DefaultPubKeys(loadDotSSH bool) ([]PubKey, error) {
|
||||
ctx := context.TODO()
|
||||
func DefaultPubKeys(ctx context.Context, loadDotSSH bool) ([]PubKey, error) {
|
||||
// Read $LIMA_HOME/_config/user.pub
|
||||
configDir, err := dirnames.LimaConfigDir()
|
||||
if err != nil {
|
||||
@@ -110,7 +109,7 @@ func DefaultPubKeys(loadDotSSH bool) ([]PubKey, error) {
|
||||
// no passphrase, no user@host comment
|
||||
privPath := filepath.Join(configDir, filenames.UserPrivateKey)
|
||||
if runtime.GOOS == "windows" {
|
||||
privPath, err = ioutilx.WindowsSubsystemPath(privPath)
|
||||
privPath, err = ioutilx.WindowsSubsystemPath(ctx, privPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -186,7 +185,7 @@ var sshInfo struct {
|
||||
//
|
||||
// The result always contains the IdentityFile option.
|
||||
// The result never contains the Port option.
|
||||
func CommonOpts(sshExe SSHExe, useDotSSH bool) ([]string, error) {
|
||||
func CommonOpts(ctx context.Context, sshExe SSHExe, useDotSSH bool) ([]string, error) {
|
||||
configDir, err := dirnames.LimaConfigDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -197,7 +196,7 @@ func CommonOpts(sshExe SSHExe, useDotSSH bool) ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
var opts []string
|
||||
idf, err := identityFileEntry(privateKeyPath)
|
||||
idf, err := identityFileEntry(ctx, privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,7 +231,7 @@ func CommonOpts(sshExe SSHExe, useDotSSH bool) ([]string, error) {
|
||||
// Fail on permission-related and other path errors
|
||||
return nil, err
|
||||
}
|
||||
idf, err = identityFileEntry(privateKeyPath)
|
||||
idf, err = identityFileEntry(ctx, privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -252,7 +251,7 @@ func CommonOpts(sshExe SSHExe, useDotSSH bool) ([]string, error) {
|
||||
|
||||
sshInfo.Do(func() {
|
||||
sshInfo.aesAccelerated = detectAESAcceleration()
|
||||
sshInfo.openSSH = detectOpenSSHInfo(sshExe)
|
||||
sshInfo.openSSH = detectOpenSSHInfo(ctx, sshExe)
|
||||
})
|
||||
|
||||
if sshInfo.openSSH.GSSAPISupported {
|
||||
@@ -284,9 +283,9 @@ func CommonOpts(sshExe SSHExe, useDotSSH bool) ([]string, error) {
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func identityFileEntry(privateKeyPath string) (string, error) {
|
||||
func identityFileEntry(ctx context.Context, privateKeyPath string) (string, error) {
|
||||
if runtime.GOOS == "windows" {
|
||||
privateKeyPath, err := ioutilx.WindowsSubsystemPath(privateKeyPath)
|
||||
privateKeyPath, err := ioutilx.WindowsSubsystemPath(ctx, privateKeyPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -296,18 +295,18 @@ func identityFileEntry(privateKeyPath string) (string, error) {
|
||||
}
|
||||
|
||||
// SSHOpts adds the following options to CommonOptions: User, ControlMaster, ControlPath, ControlPersist.
|
||||
func SSHOpts(sshExe SSHExe, instDir, username string, useDotSSH, forwardAgent, forwardX11, forwardX11Trusted bool) ([]string, error) {
|
||||
func SSHOpts(ctx context.Context, sshExe SSHExe, instDir, username string, useDotSSH, forwardAgent, forwardX11, forwardX11Trusted bool) ([]string, error) {
|
||||
controlSock := filepath.Join(instDir, filenames.SSHSock)
|
||||
if len(controlSock) >= osutil.UnixPathMax {
|
||||
return nil, fmt.Errorf("socket path %q is too long: >= UNIX_PATH_MAX=%d", controlSock, osutil.UnixPathMax)
|
||||
}
|
||||
opts, err := CommonOpts(sshExe, useDotSSH)
|
||||
opts, err := CommonOpts(ctx, sshExe, useDotSSH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
controlPath := fmt.Sprintf(`ControlPath="%s"`, controlSock)
|
||||
if runtime.GOOS == "windows" {
|
||||
controlSock, err = ioutilx.WindowsSubsystemPath(controlSock)
|
||||
controlSock, err = ioutilx.WindowsSubsystemPath(ctx, controlSock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -370,9 +369,8 @@ var (
|
||||
openSSHInfosRW sync.RWMutex
|
||||
)
|
||||
|
||||
func detectOpenSSHInfo(sshExe SSHExe) openSSHInfo {
|
||||
func detectOpenSSHInfo(ctx context.Context, sshExe SSHExe) openSSHInfo {
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
info openSSHInfo
|
||||
exe sshExecutable
|
||||
stderr bytes.Buffer
|
||||
@@ -410,8 +408,8 @@ func detectOpenSSHInfo(sshExe SSHExe) openSSHInfo {
|
||||
return info
|
||||
}
|
||||
|
||||
func DetectOpenSSHVersion(sshExe SSHExe) semver.Version {
|
||||
return detectOpenSSHInfo(sshExe).Version
|
||||
func DetectOpenSSHVersion(ctx context.Context, sshExe SSHExe) semver.Version {
|
||||
return detectOpenSSHInfo(ctx, sshExe).Version
|
||||
}
|
||||
|
||||
// detectValidPublicKey returns whether content represent a public key.
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func TestDefaultPubKeys(t *testing.T) {
|
||||
keys, _ := DefaultPubKeys(true)
|
||||
keys, _ := DefaultPubKeys(t.Context(), true)
|
||||
t.Logf("found %d public keys", len(keys))
|
||||
for _, key := range keys {
|
||||
t.Logf("%s: %q", key.Filename, key.Content)
|
||||
|
||||
@@ -18,7 +18,7 @@ func FuzzLoadYAMLByFilePath(f *testing.F) {
|
||||
localFile := filepath.Join(t.TempDir(), "yaml_file.yml")
|
||||
err := os.WriteFile(localFile, fileContents, 0o600)
|
||||
assert.NilError(t, err)
|
||||
_, _ = LoadYAMLByFilePath(localFile)
|
||||
_, _ = LoadYAMLByFilePath(t.Context(), localFile)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,6 +34,6 @@ func FuzzInspect(f *testing.F) {
|
||||
assert.NilError(t, err)
|
||||
err = os.WriteFile(limaVersionFile, limaVersion, 0o600)
|
||||
assert.NilError(t, err)
|
||||
_, _ = Inspect("fuzz-instance")
|
||||
_, _ = Inspect(t.Context(), "fuzz-instance")
|
||||
})
|
||||
}
|
||||
@@ -71,7 +71,7 @@ type Instance struct {
|
||||
|
||||
// Inspect returns err only when the instance does not exist (os.ErrNotExist).
|
||||
// Other errors are returned as *Instance.Errors.
|
||||
func Inspect(instName string) (*Instance, error) {
|
||||
func Inspect(ctx context.Context, instName string) (*Instance, error) {
|
||||
inst := &Instance{
|
||||
Name: instName,
|
||||
// TODO: support customizing hostname
|
||||
@@ -86,7 +86,7 @@ func Inspect(instName string) (*Instance, error) {
|
||||
// Make sure inst.Dir is set, even when YAML validation fails
|
||||
inst.Dir = instDir
|
||||
yamlPath := filepath.Join(instDir, filenames.LimaYAML)
|
||||
y, err := LoadYAMLByFilePath(yamlPath)
|
||||
y, err := LoadYAMLByFilePath(ctx, yamlPath)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, err
|
||||
@@ -114,7 +114,7 @@ func Inspect(instName string) (*Instance, error) {
|
||||
inst.Status = StatusBroken
|
||||
inst.Errors = append(inst.Errors, fmt.Errorf("failed to connect to %q: %w", haSock, err))
|
||||
} else {
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), 3*time.Second)
|
||||
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||
defer cancel()
|
||||
info, err := haClient.Info(ctx)
|
||||
if err != nil {
|
||||
@@ -150,7 +150,7 @@ func Inspect(instName string) (*Instance, error) {
|
||||
inst.Protected = true
|
||||
}
|
||||
|
||||
inspectStatus(instDir, inst, y)
|
||||
inspectStatus(ctx, instDir, inst, y)
|
||||
|
||||
tmpl, err := template.New("format").Parse(y.Message)
|
||||
if err != nil {
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
|
||||
package store
|
||||
|
||||
import "github.com/lima-vm/lima/v2/pkg/limayaml"
|
||||
import (
|
||||
"context"
|
||||
|
||||
func inspectStatus(instDir string, inst *Instance, y *limayaml.LimaYAML) {
|
||||
"github.com/lima-vm/lima/v2/pkg/limayaml"
|
||||
)
|
||||
|
||||
func inspectStatus(_ context.Context, instDir string, inst *Instance, y *limayaml.LimaYAML) {
|
||||
inspectStatusWithPIDFiles(instDir, inst, y)
|
||||
}
|
||||
|
||||
func GetSSHAddress(_ string) (string, error) {
|
||||
func GetSSHAddress(_ context.Context, _ string) (string, error) {
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/lima-vm/lima/v2/pkg/limayaml"
|
||||
)
|
||||
|
||||
func inspectStatus(instDir string, inst *Instance, y *limayaml.LimaYAML) {
|
||||
func inspectStatus(ctx context.Context, instDir string, inst *Instance, y *limayaml.LimaYAML) {
|
||||
if inst.VMType == limayaml.WSL2 {
|
||||
status, err := GetWslStatus(inst.Name)
|
||||
if err != nil {
|
||||
@@ -27,7 +27,7 @@ func inspectStatus(instDir string, inst *Instance, y *limayaml.LimaYAML) {
|
||||
inst.SSHLocalPort = 22
|
||||
|
||||
if inst.Status == StatusRunning {
|
||||
sshAddr, err := GetSSHAddress(inst.Name)
|
||||
sshAddr, err := GetSSHAddress(ctx, inst.Name)
|
||||
if err == nil {
|
||||
inst.SSHAddress = sshAddr
|
||||
} else {
|
||||
@@ -124,8 +124,7 @@ func GetWslStatus(instName string) (string, error) {
|
||||
// 168.1.1.1 [10.0.0.1]
|
||||
// But busybox hostname does not implement --all-ip-addresses:
|
||||
// hostname: unrecognized option: I
|
||||
func GetSSHAddress(instName string) (string, error) {
|
||||
ctx := context.TODO()
|
||||
func GetSSHAddress(ctx context.Context, instName string) (string, error) {
|
||||
distroName := "lima-" + instName
|
||||
// Ubuntu
|
||||
cmd := exec.CommandContext(ctx, "wsl.exe", "-d", distroName, "bash", "-c", `hostname -I | cut -d ' ' -f1`)
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -131,7 +132,7 @@ func DiskDir(name string) (string, error) {
|
||||
}
|
||||
|
||||
// LoadYAMLByFilePath loads and validates the yaml.
|
||||
func LoadYAMLByFilePath(filePath string) (*limayaml.LimaYAML, error) {
|
||||
func LoadYAMLByFilePath(ctx context.Context, filePath string) (*limayaml.LimaYAML, error) {
|
||||
// We need to use the absolute path because it may be used to determine hostSocket locations.
|
||||
absPath, err := filepath.Abs(filePath)
|
||||
if err != nil {
|
||||
@@ -141,7 +142,7 @@ func LoadYAMLByFilePath(filePath string) (*limayaml.LimaYAML, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y, err := limayaml.Load(yContent, absPath)
|
||||
y, err := limayaml.Load(ctx, yContent, absPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
var NetworkData = sync.OnceValues(func() ([]NetworkDataType, error) {
|
||||
b, err := SystemProfiler("SPNetworkDataType")
|
||||
b, err := SystemProfiler(context.Background(), "SPNetworkDataType")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -27,8 +27,7 @@ var NetworkData = sync.OnceValues(func() ([]NetworkDataType, error) {
|
||||
return networkData.SPNetworkDataType, nil
|
||||
})
|
||||
|
||||
func SystemProfiler(dataType string) ([]byte, error) {
|
||||
ctx := context.TODO()
|
||||
func SystemProfiler(ctx context.Context, dataType string) ([]byte, error) {
|
||||
exe, err := exec.LookPath("system_profiler")
|
||||
if err != nil {
|
||||
// $PATH may lack /usr/sbin
|
||||
|
||||
@@ -15,8 +15,7 @@ type CommandLineJSON []struct {
|
||||
}
|
||||
|
||||
// GetProcessCommandLine returns a slice of string containing all commandlines for a given process name.
|
||||
func GetProcessCommandLine(name string) ([]string, error) {
|
||||
ctx := context.TODO()
|
||||
func GetProcessCommandLine(ctx context.Context, name string) ([]string, error) {
|
||||
out, err := exec.CommandContext(ctx,
|
||||
"powershell.exe",
|
||||
"-nologo",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package windows
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -13,13 +14,13 @@ import (
|
||||
var vmIDRegex = regexp.MustCompile(`--vm-id\s\{(?P<vmID>.{36})\}`)
|
||||
|
||||
// GetInstanceVMID returns the VM ID of a running WSL instance.
|
||||
func GetInstanceVMID(instanceName string) (string, error) {
|
||||
func GetInstanceVMID(ctx context.Context, instanceName string) (string, error) {
|
||||
distroID, err := GetDistroID(instanceName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cmdLines, err := GetProcessCommandLine("wslhost.exe")
|
||||
cmdLines, err := GetProcessCommandLine(ctx, "wslhost.exe")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user