This repository has been archived by the owner on Oct 11, 2023. It is now read-only.
/
preload.go
132 lines (115 loc) · 2.94 KB
/
preload.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package control
import (
"compress/gzip"
"context"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"regexp"
"strings"
"github.com/rancher/os/config"
"github.com/rancher/os/pkg/docker"
"github.com/rancher/os/pkg/log"
"github.com/codegangsta/cli"
dockerClient "github.com/docker/engine-api/client"
"github.com/docker/engine-api/types"
)
const (
userImagesPreloadDirectory = "/var/lib/rancher/preload/docker"
)
func preloadImagesAction(c *cli.Context) error {
err := PreloadImages(docker.NewDefaultClient, userImagesPreloadDirectory)
if err != nil {
log.Errorf("Failed to preload user images: %v", err)
}
return err
}
func shouldLoad(file string) bool {
if strings.HasSuffix(file, ".done") {
return false
}
if _, err := os.Stat(fmt.Sprintf("%s.done", file)); err == nil {
return false
}
return true
}
func PreloadImages(clientFactory func() (dockerClient.APIClient, error), imagesDir string) error {
var client dockerClient.APIClient
clientInitialized := false
if _, err := os.Stat(imagesDir); os.IsNotExist(err) {
if err = os.MkdirAll(imagesDir, 0755); err != nil {
return err
}
} else if err != nil {
return err
}
// try to load predefined user images
if imagesDir == userImagesPreloadDirectory {
oldUserImgName := path.Join(config.ImagesPath, config.UserImages)
userImgfile, err := os.Stat(oldUserImgName)
if err == nil {
newUserImgName := path.Join(userImagesPreloadDirectory, userImgfile.Name())
if _, err = os.Stat(newUserImgName); os.IsNotExist(err) {
if err := os.Symlink(oldUserImgName, newUserImgName); err != nil {
log.Error(err)
}
}
}
}
files, err := ioutil.ReadDir(imagesDir)
if err != nil {
return err
}
for _, file := range files {
filename := path.Join(imagesDir, file.Name())
if !shouldLoad(filename) {
log.Infof("Skipping to preload the file: %s", filename)
continue
}
image, err := os.Open(filename)
if err != nil {
return err
}
defer image.Close()
var imageReader io.Reader
imageReader = image
match, err := regexp.MatchString(".t?gz$", file.Name())
if err != nil {
return err
}
if match {
imageReader, err = gzip.NewReader(image)
if err != nil {
return err
}
}
if !clientInitialized {
client, err = clientFactory()
if err != nil {
return err
}
clientInitialized = true
}
var imageLoadResponse types.ImageLoadResponse
if imageLoadResponse, err = client.ImageLoad(context.Background(), imageReader, false); err != nil {
return err
}
cfg := config.LoadConfig()
if cfg.Rancher.PreloadWait {
if _, err := ioutil.ReadAll(imageLoadResponse.Body); err != nil {
return err
}
}
log.Infof("Finished to load image %s", filename)
log.Infof("Creating done stamp file for image %s", filename)
doneStamp, err := os.Create(fmt.Sprintf("%s.done", filename))
if err != nil {
return err
}
defer doneStamp.Close()
log.Infof("Finished to created the done stamp file for image %s", filename)
}
return nil
}