core: rework host to guest file movements. (#1538)

Signed-off-by: Abiola Ibrahim <git@abiosoft.com>
This commit is contained in:
Abiola Ibrahim
2026-03-10 20:49:00 +01:00
committed by GitHub
parent faf0e8b5e3
commit c898071da7
7 changed files with 38 additions and 42 deletions
+1 -6
View File
@@ -339,12 +339,7 @@ func (c colimaApp) SSH(args ...string) error {
// the errors returned here is not critical and thereby silenced.
// the goal is to prevent unnecessary warning message from Lima.
log.Trace(fmt.Errorf("error checking if PWD is mounted: %w", err))
// fallback to the user's homedir
username, err := c.guest.User()
if err == nil {
workDir = "/home/" + username + ".linux"
}
workDir = ""
}
guest := lima.New(host.New())
+7 -5
View File
@@ -119,13 +119,15 @@ func (p Provision) IsColimaMode() bool {
}
func (c Config) MountsOrDefault() []Mount {
if len(c.Mounts) > 0 {
return c.Mounts
// explicit empty list means mount home directory (matches yaml.go)
if c.Mounts != nil && len(c.Mounts) == 0 {
return []Mount{
{Location: util.HomeDir(), Writable: true},
}
}
return []Mount{
{Location: util.HomeDir(), Writable: true},
}
// nil means no mounts, non-empty means user-specified mounts
return c.Mounts
}
// AutoActivate returns if auto-activation of host client config is enabled.
+12 -11
View File
@@ -5,8 +5,8 @@ import (
"fmt"
"path/filepath"
"github.com/abiosoft/colima/config"
"github.com/abiosoft/colima/environment/container/docker"
"github.com/abiosoft/colima/util/downloader"
)
func (l limaVM) copyCerts() error {
@@ -19,31 +19,32 @@ func (l limaVM) copyCerts() error {
return nil
}
// we are utilising the host cache path as it is the only guaranteed mounted path.
// copy to cache dir
dockerCertsCacheDir := filepath.Join(config.CacheDir(), "docker-certs")
if err := l.host.RunQuiet("rm", "-rf", dockerCertsCacheDir); err != nil {
// copy certs from host to a temp location in the guest using limactl copy,
// then use sudo to move them to the final destinations.
tmpDir := "/tmp/docker-certs"
if err := l.RunQuiet("rm", "-rf", tmpDir); err != nil {
return err
}
if err := l.host.RunQuiet("mkdir", "-p", dockerCertsCacheDir); err != nil {
if err := l.RunQuiet("mkdir", "-p", tmpDir); err != nil {
return err
}
if err := l.host.RunQuiet("cp", "-R", dockerCertsDirHost+"/.", dockerCertsCacheDir); err != nil {
if err := downloader.CopyToGuest(l.host, dockerCertsDirHost, tmpDir); err != nil {
return err
}
// copy from cache to vm
// move from temp to final destinations
for _, dir := range dockerCertsDirsGuest {
// copy from cache to vm
if err := l.RunQuiet("sudo", "mkdir", "-p", dir); err != nil {
return err
}
if err := l.RunQuiet("sudo", "cp", "-R", dockerCertsCacheDir+"/.", dir); err != nil {
if err := l.RunQuiet("sudo", "cp", "-R", tmpDir+"/.", dir); err != nil {
return err
}
}
// cleanup temp
_ = l.RunQuiet("rm", "-rf", tmpDir)
return nil
}()
+5 -1
View File
@@ -20,7 +20,11 @@ func (l limaVM) Run(args ...string) error {
}
func (l limaVM) SSH(workingDir string, args ...string) error {
args = append([]string{limactl, "shell", "--workdir", workingDir, config.CurrentProfile().ID}, args...)
if workingDir == "" {
args = append([]string{limactl, "shell", config.CurrentProfile().ID}, args...)
} else {
args = append([]string{limactl, "shell", "--workdir", workingDir, config.CurrentProfile().ID}, args...)
}
a := l.Init(context.Background())
-9
View File
@@ -388,9 +388,6 @@ func newConf(ctx context.Context, conf config.Config) (l limaconfig.Config, err
return
}
l.Mounts = append(l.Mounts, limaconfig.Mount{Location: config.CacheDir(), Writable: false})
cacheOverlapFound := false
for _, m := range conf.Mounts {
var location, mountPoint string
location, err = util.CleanPath(m.Location)
@@ -405,12 +402,6 @@ func newConf(ctx context.Context, conf config.Config) (l limaconfig.Config, err
mount := limaconfig.Mount{Location: location, MountPoint: mountPoint, Writable: m.Writable}
l.Mounts = append(l.Mounts, mount)
// check if cache directory has been mounted by other mounts, and remove cache directory from mounts
if strings.HasPrefix(config.CacheDir(), location) && !cacheOverlapFound {
l.Mounts = l.Mounts[1:]
cacheOverlapFound = true
}
}
}
+3 -6
View File
@@ -48,15 +48,14 @@ func Test_checkOverlappingMounts(t *testing.T) {
func Test_config_Mounts(t *testing.T) {
fsutil.FS = fsutil.FakeFS
tests := []struct {
mounts []string
isDefault bool
includesCache bool
mounts []string
isDefault bool
}{
{mounts: []string{"/User/user", "/tmp/another"}},
{mounts: []string{"/User/another", "/User/something", "/User/else"}},
{mounts: []string{}, isDefault: true},
{mounts: nil},
{mounts: []string{util.HomeDir()}, includesCache: true},
{mounts: []string{util.HomeDir()}},
}
for i, tt := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
@@ -79,8 +78,6 @@ func Test_config_Mounts(t *testing.T) {
expectedLocations := tt.mounts
if tt.isDefault {
expectedLocations = []string{"~"}
} else if !tt.includesCache {
expectedLocations = append([]string{config.CacheDir()}, tt.mounts...)
}
sameMounts := func(expectedLocations []string, mounts []limaconfig.Mount) bool {
+10 -4
View File
@@ -54,13 +54,13 @@ func init() {
// DownloadToGuest downloads file at url and saves it in the destination.
//
// In the implementation, the file is downloaded (and cached) on the host, but copied to the desired
// destination for the guest.
// In the implementation, the file is downloaded (and cached) on the host,
// then copied to the guest using limactl copy.
// filename must be an absolute path and a directory on the guest that does not require root access.
func DownloadToGuest(host hostActions, guest guestActions, r Request, filename string) error {
// if file is on the filesystem, no need for download. A copy suffices
if strings.HasPrefix(r.URL, "/") {
return guest.RunQuiet("cp", r.URL, filename)
return CopyToGuest(host, r.URL, filename)
}
cacheFile, err := Download(host, r)
@@ -68,7 +68,13 @@ func DownloadToGuest(host hostActions, guest guestActions, r Request, filename s
return err
}
return guest.RunQuiet("cp", cacheFile, filename)
return CopyToGuest(host, cacheFile, filename)
}
// CopyToGuest copies a file or directory from the host to the guest VM using limactl copy.
func CopyToGuest(host hostActions, src, dest string) error {
instanceName := config.CurrentProfile().ID
return host.RunQuiet("limactl", "copy", "-r", src, instanceName+":"+dest)
}
// Download downloads file at url and returns the location of the downloaded file.