Skip to content

Commit 2d570a0

Browse files
author
maxing.lan
committed
feat: nydusify: add backend configure support of optimize subcommand
When localfs-backend is true (default is false), still pull whole image to build optimized image; otherwise, use registry backend to fetch needed chunk during building process. Signed-off-by: maxing.lan <[email protected]>
1 parent dec2e4b commit 2d570a0

File tree

4 files changed

+94
-7
lines changed

4 files changed

+94
-7
lines changed

contrib/nydusify/cmd/nydusify.go

+49-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ func main() {
200200
Required: false,
201201
Value: false,
202202
Usage: "Enable debug log level, overwrites the 'log-level' option",
203-
EnvVars: []string{"DEBUG_LOG_LEVEL"}},
203+
EnvVars: []string{"DEBUG_LOG_LEVEL"},
204+
},
204205
&cli.StringFlag{
205206
Name: "log-level",
206207
Aliases: []string{"l"},
@@ -1223,10 +1224,54 @@ func main() {
12231224
Value: "0MB",
12241225
Usage: "Chunk size for pushing a blob layer in chunked",
12251226
},
1227+
1228+
&cli.StringFlag{
1229+
Name: "source-backend-type",
1230+
Value: "",
1231+
Usage: "Type of storage backend, enable verification of file data in Nydus image if specified, possible values: 'oss', 's3', 'localfs'",
1232+
EnvVars: []string{"BACKEND_TYPE"},
1233+
},
1234+
&cli.StringFlag{
1235+
Name: "source-backend-config",
1236+
Value: "",
1237+
Usage: "Json string for storage backend configuration",
1238+
EnvVars: []string{"BACKEND_CONFIG"},
1239+
},
1240+
&cli.PathFlag{
1241+
Name: "source-backend-config-file",
1242+
Value: "",
1243+
TakesFile: true,
1244+
Usage: "Json configuration file for storage backend",
1245+
EnvVars: []string{"BACKEND_CONFIG_FILE"},
1246+
},
12261247
},
12271248
Action: func(c *cli.Context) error {
12281249
setupLogLevel(c)
12291250

1251+
backendType, backendConfig, err := getBackendConfig(c, "", false)
1252+
if err != nil {
1253+
return err
1254+
} else if backendConfig == "" {
1255+
1256+
backendType = "registry"
1257+
parsed, err := reference.ParseNormalizedNamed(c.String("target"))
1258+
if err != nil {
1259+
return err
1260+
}
1261+
1262+
backendConfigStruct, err := utils.NewRegistryBackendConfig(parsed, c.Bool("target-insecure"))
1263+
if err != nil {
1264+
return errors.Wrap(err, "parse registry backend configuration")
1265+
}
1266+
1267+
bytes, err := json.Marshal(backendConfigStruct)
1268+
if err != nil {
1269+
return errors.Wrap(err, "marshal registry backend configuration")
1270+
}
1271+
backendConfig = string(bytes)
1272+
1273+
}
1274+
12301275
pushChunkSize, err := humanize.ParseBytes(c.String("push-chunk-size"))
12311276
if err != nil {
12321277
return errors.Wrap(err, "invalid --push-chunk-size option")
@@ -1248,6 +1293,9 @@ func main() {
12481293

12491294
PushChunkSize: int64(pushChunkSize),
12501295
PrefetchFilesPath: c.String("prefetch-files"),
1296+
1297+
BackendType: backendType,
1298+
BackendConfig: backendConfig,
12511299
}
12521300

12531301
return optimizer.Optimize(context.Background(), opt)

contrib/nydusify/pkg/optimizer/builder.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ func isSignalKilled(err error) bool {
1919
}
2020

2121
type BuildOption struct {
22-
BuilderPath string
23-
PrefetchFilesPath string
24-
BootstrapPath string
22+
BuilderPath string
23+
PrefetchFilesPath string
24+
BootstrapPath string
25+
BackendType string
26+
BackendConfig string
27+
// `BlobDir` is used to store optimized blob,
28+
// Beside, `BlobDir` is also used to store the original blobs when backend is localfs
2529
BlobDir string
2630
OutputBootstrapPath string
2731
OutputJSONPath string
@@ -42,14 +46,21 @@ func Build(option BuildOption) (string, error) {
4246
option.PrefetchFilesPath,
4347
"--bootstrap",
4448
option.BootstrapPath,
45-
"--blob-dir",
49+
"--output-blob-dir",
4650
option.BlobDir,
4751
"--output-bootstrap",
4852
option.OutputBootstrapPath,
4953
"--output-json",
5054
outputJSONPath,
5155
}
5256

57+
if option.BackendType == "localfs" {
58+
args = append(args, "--blob-dir", option.BlobDir)
59+
} else {
60+
args = append(args, "--backend-type", option.BackendType)
61+
args = append(args, "--backend-config", option.BackendConfig)
62+
}
63+
5364
ctx := context.Background()
5465
var cancel context.CancelFunc
5566
if option.Timeout != nil {

contrib/nydusify/pkg/optimizer/optimizer.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ type Opt struct {
6161
Platforms string
6262

6363
PushChunkSize int64
64+
65+
BackendType string
66+
BackendConfig string
6467
}
6568

6669
// the information generated during building
@@ -269,8 +272,10 @@ func Optimize(ctx context.Context, opt Opt) error {
269272
}
270273
defer os.RemoveAll(buildDir)
271274

272-
if err := fetchBlobs(ctx, opt, buildDir); err != nil {
273-
return errors.Wrap(err, "prepare nydus blobs")
275+
if opt.BackendType == "localfs" {
276+
if err := fetchBlobs(ctx, opt, buildDir); err != nil {
277+
return errors.Wrap(err, "prepare nydus blobs")
278+
}
274279
}
275280

276281
originalBootstrap := filepath.Join(buildDir, "nydus_bootstrap")
@@ -289,12 +294,17 @@ func Optimize(ctx context.Context, opt Opt) error {
289294

290295
compressAlgo := bootstrapDesc.Digest.Algorithm().String()
291296
blobDir := filepath.Join(buildDir + "/content/blobs/" + compressAlgo)
297+
if err := os.MkdirAll(blobDir, 0755); err != nil {
298+
return errors.Wrap(err, "create blob directory")
299+
}
292300
outPutJSONPath := filepath.Join(buildDir, "output.json")
293301
newBootstrapPath := filepath.Join(buildDir, "optimized_bootstrap")
294302
builderOpt := BuildOption{
295303
BuilderPath: opt.NydusImagePath,
296304
PrefetchFilesPath: opt.PrefetchFilesPath,
297305
BootstrapPath: originalBootstrap,
306+
BackendType: opt.BackendType,
307+
BackendConfig: opt.BackendConfig,
298308
BlobDir: blobDir,
299309
OutputBootstrapPath: newBootstrapPath,
300310
OutputJSONPath: outPutJSONPath,

docs/nydusify.md

+18
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,24 @@ nerdctl --snapshotter nydus run \
262262

263263
The original container ID need to be a full container ID rather than an abbreviation.
264264

265+
## Optimize nydus image from prefetch files
266+
267+
The nydusify optimize command can optimize a nydus image from prefetch files, prefetch files are file access patterns during container startup. This will generate a new bootstrap and a new blob wich contains all data indicated by prefetch files.
268+
269+
The content of prefetch files likes this:
270+
```
271+
/path/to/file1 start_offset1-end_offset1, start_offset2-end_offset2, ...
272+
/path/to/file2 start_offset1-end_offset1, start_offset2-end_offset2, ...
273+
```
274+
275+
``` shell
276+
nydusify optimize \
277+
--nydus-image /path/to/nydus-image \
278+
--source myregistry/repo:tag-nydus \
279+
--target myregistry/repo:tag-nydus-optimized \
280+
--prefetch-files /path/to/prefetch-files \
281+
```
282+
265283
## More Nydusify Options
266284

267285
See `nydusify convert/check/mount --help`

0 commit comments

Comments
 (0)