Skip to content

Commit 1f046c3

Browse files
author
Yang Kaiyong
committed
nydusify(feat): support for specifing log file and concurrently processing external model manifests
Signed-off-by: Yang Kaiyong <yangkaiyong.yky@antgroup.com>
1 parent e8856d5 commit 1f046c3

File tree

6 files changed

+114
-24
lines changed

6 files changed

+114
-24
lines changed

contrib/nydusify/cmd/nydusify.go

+34-15
Original file line numberDiff line numberDiff line change
@@ -179,21 +179,8 @@ func getPrefetchPatterns(c *cli.Context) (string, error) {
179179
return patterns, nil
180180
}
181181

182-
func main() {
183-
logrus.SetFormatter(&logrus.TextFormatter{
184-
FullTimestamp: true,
185-
})
186-
187-
version := fmt.Sprintf("\nVersion : %s\nRevision : %s\nGo version : %s\nBuild time : %s", gitVersion, revision, runtime.Version(), buildTime)
188-
189-
app := &cli.App{
190-
Name: "Nydusify",
191-
Usage: "Nydus utility tool to build, convert, verify and view container images",
192-
Version: version,
193-
}
194-
195-
// global options
196-
app.Flags = []cli.Flag{
182+
func getGlobalFlags() []cli.Flag {
183+
return []cli.Flag{
197184
&cli.BoolFlag{
198185
Name: "debug",
199186
Aliases: []string{"D"},
@@ -208,7 +195,30 @@ func main() {
208195
Usage: "Set log level (panic, fatal, error, warn, info, debug, trace)",
209196
EnvVars: []string{"LOG_LEVEL"},
210197
},
198+
&cli.StringFlag{
199+
Name: "log-file",
200+
Required: false,
201+
Usage: "Write logs to a file",
202+
EnvVars: []string{"LOG_FILE"},
203+
},
211204
}
205+
}
206+
207+
func main() {
208+
logrus.SetFormatter(&logrus.TextFormatter{
209+
FullTimestamp: true,
210+
})
211+
212+
version := fmt.Sprintf("\nVersion : %s\nRevision : %s\nGo version : %s\nBuild time : %s", gitVersion, revision, runtime.Version(), buildTime)
213+
214+
app := &cli.App{
215+
Name: "Nydusify",
216+
Usage: "Nydus utility tool to build, convert, verify and view container images",
217+
Version: version,
218+
}
219+
220+
// global options
221+
app.Flags = getGlobalFlags()
212222

213223
app.Commands = []*cli.Command{
214224
{
@@ -1439,4 +1449,13 @@ func setupLogLevel(c *cli.Context) {
14391449
}
14401450

14411451
logrus.SetLevel(logLevel)
1452+
1453+
if c.String("log-file") != "" {
1454+
f, err := os.OpenFile(c.String("log-file"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
1455+
if err != nil {
1456+
logrus.Errorf("failed to open log file: %+v", err)
1457+
return
1458+
}
1459+
logrus.SetOutput(f)
1460+
}
14421461
}

contrib/nydusify/cmd/nydusify_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import (
1212
"os"
1313
"testing"
1414

15+
"github.com/agiledragon/gomonkey/v2"
16+
"github.com/sirupsen/logrus"
17+
"github.com/stretchr/testify/assert"
1518
"github.com/stretchr/testify/require"
1619
"github.com/urfave/cli/v2"
1720
)
@@ -341,3 +344,50 @@ func TestGetPrefetchPatterns(t *testing.T) {
341344
require.NoError(t, err)
342345
require.Equal(t, "/", patterns)
343346
}
347+
348+
func TestGetGlobalFlags(t *testing.T) {
349+
flags := getGlobalFlags()
350+
require.Equal(t, 3, len(flags))
351+
}
352+
353+
func TestSetupLogLevelWithLogFile(t *testing.T) {
354+
logFilePath := "test_log_file.log"
355+
defer os.Remove(logFilePath)
356+
357+
c := &cli.Context{}
358+
359+
patches := gomonkey.ApplyMethodSeq(c, "String", []gomonkey.OutputCell{
360+
{Values: []interface{}{"info"}, Times: 1},
361+
{Values: []interface{}{"test_log_file.log"}, Times: 2},
362+
})
363+
defer patches.Reset()
364+
setupLogLevel(c)
365+
366+
file, err := os.Open(logFilePath)
367+
assert.NoError(t, err)
368+
assert.NotNil(t, file)
369+
file.Close()
370+
371+
logrusOutput := logrus.StandardLogger().Out
372+
assert.NotNil(t, logrusOutput)
373+
374+
logrus.Info("This is a test log message")
375+
content, err := os.ReadFile(logFilePath)
376+
assert.NoError(t, err)
377+
assert.Contains(t, string(content), "This is a test log message")
378+
}
379+
380+
func TestSetupLogLevelWithInvalidLogFile(t *testing.T) {
381+
382+
c := &cli.Context{}
383+
384+
patches := gomonkey.ApplyMethodSeq(c, "String", []gomonkey.OutputCell{
385+
{Values: []interface{}{"info"}, Times: 1},
386+
{Values: []interface{}{"test/test_log_file.log"}, Times: 2},
387+
})
388+
defer patches.Reset()
389+
setupLogLevel(c)
390+
391+
logrusOutput := logrus.StandardLogger().Out
392+
assert.NotNil(t, logrusOutput)
393+
}

contrib/nydusify/go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ require (
3939
require (
4040
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
4141
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2 // indirect
42-
github.com/BraveY/snapshotter-converter v0.0.6 // indirect
42+
github.com/BraveY/snapshotter-converter v0.0.5 // indirect
4343
github.com/CloudNativeAI/model-spec v0.0.2 // indirect
4444
github.com/Microsoft/go-winio v0.6.2 // indirect
4545
github.com/Microsoft/hcsshim v0.11.5 // indirect

contrib/nydusify/pkg/converter/converter.go

-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,6 @@ func convertModelArtifact(ctx context.Context, opt Opt) error {
262262
ChunkSize: opt.ChunkSize,
263263
FromDir: contextDir,
264264
AttributesPath: attributesPath,
265-
Crc32: true,
266265
}
267266
_, externalBlobDigest, err := packWithAttributes(ctx, packOption, tmpDir)
268267
if err != nil {

contrib/nydusify/pkg/external/modctl/remote.go

+28-6
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import (
1010
"io"
1111
"os"
1212
"strconv"
13+
"sync"
1314

1415
"github.com/dragonflyoss/nydus/contrib/nydusify/pkg/snapshotter/external/backend"
1516
"github.com/dragonflyoss/nydus/contrib/nydusify/pkg/utils"
1617
"github.com/pkg/errors"
1718
"github.com/sirupsen/logrus"
19+
"golang.org/x/sync/errgroup"
1820

1921
modelspec "github.com/CloudNativeAI/model-spec/specs-go/v1"
2022
pkgPvd "github.com/dragonflyoss/nydus/contrib/nydusify/pkg/provider"
@@ -80,14 +82,34 @@ func initRemoteHandler(handler *RemoteHandler) error {
8082
}
8183

8284
func (handler *RemoteHandler) Handle(ctx context.Context) (*backend.Backend, []backend.FileAttribute, error) {
83-
var fileAttrs []backend.FileAttribute
85+
var (
86+
fileAttrs []backend.FileAttribute
87+
mu sync.Mutex
88+
eg *errgroup.Group
89+
)
90+
ctx, cancel := context.WithCancel(ctx)
91+
defer cancel()
92+
eg, ctx = errgroup.WithContext(ctx)
93+
eg.SetLimit(5)
94+
8495
for idx, layer := range handler.manifest.Layers {
85-
fa, err := handler.handle(ctx, layer, int32(idx))
86-
if err != nil {
87-
return nil, nil, errors.Wrap(err, "handle layer failed")
88-
}
89-
fileAttrs = append(fileAttrs, fa...)
96+
eg.Go(func() error {
97+
fa, err := handler.handle(ctx, layer, int32(idx))
98+
if err != nil {
99+
cancel()
100+
return err
101+
}
102+
mu.Lock()
103+
fileAttrs = append(fileAttrs, fa...)
104+
mu.Unlock()
105+
return nil
106+
})
90107
}
108+
109+
if err := eg.Wait(); err != nil {
110+
return nil, nil, errors.Wrap(err, "wait for handle failed")
111+
}
112+
91113
bkd, err := handler.backend()
92114
if err != nil {
93115
return nil, nil, errors.Wrap(err, "get backend failed")

contrib/nydusify/pkg/snapshotter/external/external.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func RemoteHandle(ctx context.Context, opts Options) error {
9595
attributes = append(attributes, Attribute{
9696
Pattern: p,
9797
})
98-
logrus.Infof("file attr: %s, file_mode: %o", p, file.Mode)
98+
logrus.Debugf("file attr: %s, file_mode: %o", p, file.Mode)
9999
}
100100

101101
backendBytes, err := json.MarshalIndent(bkd, "", " ")

0 commit comments

Comments
 (0)