Skip to content

Commit 2cff782

Browse files
committed
profiles: Preemptive pull workload images
Signed-off-by: Paulo Gomes <[email protected]>
1 parent 8a35364 commit 2cff782

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

internal/images/images.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package images
22

33
import (
4-
"errors"
54
"fmt"
6-
"io/fs"
75
"log/slog"
86
"os"
97
"sync"
@@ -53,7 +51,7 @@ func pullExpired() (bool, error) {
5351
fn := files.ImagesLastCheckedPath()
5452
fi, err := os.Stat(fn)
5553
if err != nil {
56-
if !errors.Is(err, fs.ErrNotExist) {
54+
if !os.IsNotExist(err) {
5755
return false, fmt.Errorf("cannot stat %q: %w", fn, err)
5856
}
5957
if err := os.WriteFile(fn, []byte{}, files.FileMode); err != nil {
@@ -76,6 +74,19 @@ func pullExpired() (bool, error) {
7674
return false, nil
7775
}
7876

77+
func PreemptWorkloadImages(cfg *types.Config) {
78+
slog.Debug("Check need for the preemptive pull of workload images")
79+
fn := files.ImagesLastCheckedPath()
80+
81+
_, err := os.Stat(fn)
82+
if err != nil && os.IsNotExist(err) {
83+
fmt.Println("INFO: Preemptively pulling workload images. This only happens on first execution and aims to avoid delays opening apps.")
84+
85+
_ = PullAll(cfg)
86+
_ = os.WriteFile(fn, []byte{}, files.FileMode)
87+
}
88+
}
89+
7990
func PullAll(cfg *types.Config) error {
8091
wf, err := cfg.WorkloadFiles()
8192
if err != nil {

internal/profiles/profiles.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,15 @@ func validGitDir(path string) bool {
7474

7575
func StartFromGit(name, gitURL, path, local string) error {
7676
ln := files.ProfileConfig(name)
77+
7778
if _, err := os.Lstat(ln); err == nil {
78-
return fmt.Errorf("profile %q is already started", name)
79+
// Wayland is not cleaning up profile state after closure.
80+
if !strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") {
81+
return fmt.Errorf("profile %q is already started", name)
82+
}
83+
if err = os.Remove(ln); err != nil {
84+
return fmt.Errorf("failed to remove leftover profile symlink: %w", err)
85+
}
7986
}
8087

8188
dir, err := files.GitDirPath(gitURL)
@@ -177,11 +184,18 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) {
177184
return err
178185
}
179186

187+
fi, err := os.Lstat(files.ContainerRunnerBinary)
188+
if err != nil || !fi.Mode().IsRegular() {
189+
return fmt.Errorf("could not find docker or podman")
190+
}
191+
180192
err = images.PullImageIfNotPresent(profile.Image)
181193
if err != nil {
182194
return fmt.Errorf("cannot pull profile image: %w", err)
183195
}
184196

197+
go images.PreemptWorkloadImages(cfg)
198+
185199
if profile.Gpus != "" {
186200
if !gpu.Supported() {
187201
profile.Gpus = ""
@@ -225,6 +239,7 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) {
225239
err = err1
226240
}
227241
}
242+
228243
wg.Done()
229244
}()
230245

internal/types/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ func LoadConfig(path string) (*Config, error) {
187187
return nil, fmt.Errorf("cannot unmarshal qubesome config %q: %w", path, err)
188188
}
189189

190+
cfg.RootDir = filepath.Dir(path)
191+
190192
// To avoid names being defined twice on the profiles, the name
191193
// is only defined when referring to a profile which results
192194
// on the .name field of Profiles not being populated.

0 commit comments

Comments
 (0)