Skip to content

Commit b919e72

Browse files
author
abushwang
committed
ctr-remote: add wildcard support for prefetch-list option
Signed-off-by: abushwang <[email protected]>
1 parent 8f3983e commit b919e72

File tree

5 files changed

+80
-1
lines changed

5 files changed

+80
-1
lines changed

analyzer/recorder/recorder.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ type ImageRecorder struct {
5656
recordW content.Writer
5757
recordWMu sync.Mutex
5858
recorded map[string]struct{}
59+
allPaths map[string]struct{}
60+
allPathsOnce sync.Once
5961
}
6062

6163
func NewImageRecorder(ctx context.Context, cs content.Store, img images.Image, platformMC platforms.MatchComparer) (*ImageRecorder, error) {
@@ -173,6 +175,46 @@ func (r *ImageRecorder) Record(name string) error {
173175
})
174176
}
175177

178+
// RecordGlob records all files matching the given glob pattern.
179+
// Pattern semantics follow path.Match and paths are normalized via cleanEntryName.
180+
func (r *ImageRecorder) RecordGlob(pattern string, matcher func(string, string) (bool, error)) (int, error) {
181+
if pattern == "" {
182+
return 0, nil
183+
}
184+
185+
pattern = cleanEntryName(pattern)
186+
r.ensureAllPaths()
187+
188+
var matchedCount int
189+
for name := range r.allPaths {
190+
matched, err := matcher(pattern, name)
191+
if err != nil {
192+
return matchedCount, err
193+
}
194+
if !matched {
195+
continue
196+
}
197+
if err := r.Record(name); err != nil {
198+
continue
199+
}
200+
matchedCount++
201+
}
202+
203+
return matchedCount, nil
204+
}
205+
206+
func (r *ImageRecorder) ensureAllPaths() {
207+
r.allPathsOnce.Do(func() {
208+
paths := make(map[string]struct{})
209+
for i := range r.index {
210+
for name := range r.index[i] {
211+
paths[name] = struct{}{}
212+
}
213+
}
214+
r.allPaths = paths
215+
})
216+
}
217+
176218
func (r *ImageRecorder) Commit(ctx context.Context) (digest.Digest, error) {
177219
r.recordWMu.Lock()
178220
defer r.recordWMu.Unlock()

cmd/ctr-remote/commands/optimize.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"strings"
3030
"time"
3131

32+
"github.com/bmatcuk/doublestar/v4"
3233
containerd "github.com/containerd/containerd/v2/client"
3334
"github.com/containerd/containerd/v2/cmd/ctr/commands"
3435
"github.com/containerd/containerd/v2/core/content"
@@ -129,7 +130,7 @@ var OptimizeCommand = &cli.Command{
129130
},
130131
&cli.StringFlag{
131132
Name: "prefetch-list",
132-
Usage: "path to a text file containing list of files to prefetch (one file path per line)",
133+
Usage: "path to a text file listing files/patterns to prefetch (one per line; supports glob *, ?, [], and **)",
133134
},
134135
}, samplerFlags...),
135136
Action: func(clicontext *cli.Context) error {
@@ -384,6 +385,17 @@ func analyzePrefetchList(
384385
defer rc.Close()
385386

386387
for _, filePath := range prefetchPaths {
388+
if strings.ContainsAny(filePath, "*?[") {
389+
n, err := rc.RecordGlob(filePath, doublestar.Match)
390+
if err != nil {
391+
log.G(ctx).WithError(err).Debugf("failed to record by glob %q", filePath)
392+
continue
393+
}
394+
if n == 0 {
395+
log.G(ctx).Warnf("glob pattern %q matched no files", filePath)
396+
}
397+
continue
398+
}
387399
if err := rc.Record(filePath); err != nil {
388400
log.G(ctx).WithError(err).Debugf("failed to record %q", filePath)
389401
}

cmd/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.24.0
55
toolchain go1.24.2
66

77
require (
8+
github.com/bmatcuk/doublestar/v4 v4.9.1
89
github.com/containerd/containerd/api v1.9.0
910
github.com/containerd/containerd/v2 v2.1.4
1011
github.com/containerd/go-cni v1.1.13

cmd/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
1414
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
1515
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
1616
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
17+
github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE=
18+
github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
1719
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
1820
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
1921
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=

docs/ctr-remote.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,28 @@ Other options are also available for configuring the workload.
132132
|`-t`or`--terminal`|Attach terminal to the container. This flag must be specified with `-i`|
133133
|`-i`|Attach stdin to the container|
134134

135+
### Prefetch list glob patterns
136+
137+
`ctr-remote image optimize` supports specifying a prefetch list file via `--prefetch-list`. Each line can be a path or a glob pattern. Supported patterns:
138+
139+
- `*` matches any sequence except `/` (single directory level)
140+
- `?` matches a single character except `/`
141+
- `[]` character class, e.g. `[ab]`, `[a-z]`
142+
- `**` recursive wildcard that can match across `/` (multiple directory levels)
143+
144+
Examples:
145+
146+
```
147+
/usr/bin/*
148+
/usr/lib/**/*.so
149+
/var/log/**/app.*.log
150+
/opt/data/img_[ab].png
151+
```
152+
153+
Notes:
154+
- Empty lines and lines starting with `#` are ignored.
155+
- Paths are normalized internally; both `/foo/bar` and `foo/bar` are accepted.
156+
135157
## Mounting files from the host
136158

137159
There are several cases where sharing files from host to the container during optimization is useful.

0 commit comments

Comments
 (0)