fixed charta indexing

This commit is contained in:
2026-03-31 14:40:25 +02:00
parent ec51bf6e34
commit 587ea5ba29
38 changed files with 626 additions and 358 deletions
+7 -3
View File
@@ -15,7 +15,8 @@ import (
"mstore/pkg/auxtool" "mstore/pkg/auxtool"
"mstore/pkg/terms" "mstore/pkg/terms"
yaml "go.yaml.in/yaml/v4" yaml "sigs.k8s.io/yaml"
//yaml "go.yaml.in/yaml/v4"
chart "helm.sh/helm/v4/pkg/chart/v2" chart "helm.sh/helm/v4/pkg/chart/v2"
repo "helm.sh/helm/v4/pkg/repo/v1" repo "helm.sh/helm/v4/pkg/repo/v1"
) )
@@ -52,7 +53,8 @@ func (oper *Operator) GetFile(ctx context.Context, operatorID string, params *Ge
oper.iLock.WaitAndLock(resName) oper.iLock.WaitAndLock(resName)
defer oper.iLock.Done(resName) defer oper.iLock.Done(resName)
if filename != "index.yaml" { const helmIndexName = "index.yaml"
if filename != helmIndexName {
descrExists, fileDescr, err := oper.mdb.GetFileByCollectionName(ctx, collection, filename) descrExists, fileDescr, err := oper.mdb.GetFileByCollectionName(ctx, collection, filename)
if err != nil { if err != nil {
code := http.StatusInternalServerError code := http.StatusInternalServerError
@@ -81,8 +83,10 @@ func (oper *Operator) GetFile(ctx context.Context, operatorID string, params *Ge
code := http.StatusOK code := http.StatusOK
return code, res, err return code, res, err
} }
fileDescrs, err := oper.mdb.ListFilesByCollection(ctx, collection) fileDescrs, err := oper.mdb.ListFilesByCollection(ctx, collection)
index := repo.NewIndexFile() index := repo.NewIndexFile()
url := "https://" + path.Join(oper.hostname, collection)
for _, descr := range fileDescrs { for _, descr := range fileDescrs {
if descr.Type == hcMediaType { if descr.Type == hcMediaType {
meta := &chart.Metadata{} meta := &chart.Metadata{}
@@ -91,7 +95,7 @@ func (oper *Operator) GetFile(ctx context.Context, operatorID string, params *Ge
code := http.StatusInternalServerError code := http.StatusInternalServerError
return code, res, err return code, res, err
} }
index.MustAdd(meta, descr.Name, "aaa", descr.HelmHash) index.MustAdd(meta, descr.Name, url, descr.HelmHash)
} }
} }
+11 -8
View File
@@ -11,22 +11,25 @@ import (
) )
type OperatorParams struct { type OperatorParams struct {
MainDB *maindb.Database MainDB *maindb.Database
Store *storage.Storage Store *storage.Storage
Hostname string
} }
type Operator struct { type Operator struct {
mdb *maindb.Database mdb *maindb.Database
store *storage.Storage store *storage.Storage
logg *logger.Logger logg *logger.Logger
iLock *locker.Locker iLock *locker.Locker
hostname string
} }
func NewOperator(params *OperatorParams) (*Operator, error) { func NewOperator(params *OperatorParams) (*Operator, error) {
var err error var err error
oper := &Operator{ oper := &Operator{
mdb: params.MainDB, mdb: params.MainDB,
store: params.Store, store: params.Store,
hostname: params.Hostname,
} }
oper.iLock = locker.NewLocker() oper.iLock = locker.NewLocker()
oper.logg = logger.NewLoggerWithSubject("fileoper") oper.logg = logger.NewLoggerWithSubject("fileoper")
+4 -3
View File
@@ -325,14 +325,15 @@ func (srv *Server) Build() error {
// Creating file operator // Creating file operator
srv.logg.Infof("Creating file operator") srv.logg.Infof("Creating file operator")
fileoperParams := &fileoper.OperatorParams{ fileoperParams := &fileoper.OperatorParams{
MainDB: srv.mdb, MainDB: srv.mdb,
Store: srv.stor, Store: srv.stor,
Hostname: srv.conf.Hostname,
} }
srv.fiop, err = fileoper.NewOperator(fileoperParams) srv.fiop, err = fileoper.NewOperator(fileoperParams)
if err != nil { if err != nil {
return err return err
} }
// Creating operator // Creating image operator
srv.logg.Infof("Creating operator") srv.logg.Infof("Creating operator")
imageoperParams := &imageoper.OperatorParams{ imageoperParams := &imageoper.OperatorParams{
MainDB: srv.mdb, MainDB: srv.mdb,
+9 -8
View File
@@ -1,13 +1,13 @@
module mstore module mstore
go 1.25.6 go 1.25.7
require ( require (
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/google/go-containerregistry v0.21.2 github.com/google/go-containerregistry v0.21.3
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/jmoiron/sqlx v1.4.0 github.com/jmoiron/sqlx v1.4.0
github.com/mattn/go-sqlite3 v1.14.37 github.com/mattn/go-sqlite3 v1.14.38
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.1 github.com/opencontainers/image-spec v1.1.1
github.com/spf13/cobra v1.10.2 github.com/spf13/cobra v1.10.2
@@ -29,7 +29,7 @@ require (
github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v29.2.1+incompatible // indirect github.com/docker/cli v29.3.0+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a // indirect github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a // indirect
@@ -71,7 +71,7 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.4 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect github.com/spf13/cast v1.10.0 // indirect
@@ -87,9 +87,9 @@ require (
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.47.0 // indirect golang.org/x/crypto v0.47.0 // indirect
golang.org/x/net v0.49.0 // indirect golang.org/x/net v0.49.0 // indirect
golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.19.0 // indirect golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.41.0 // indirect golang.org/x/sys v0.42.0 // indirect
golang.org/x/term v0.39.0 // indirect golang.org/x/term v0.39.0 // indirect
golang.org/x/text v0.33.0 // indirect golang.org/x/text v0.33.0 // indirect
golang.org/x/time v0.12.0 // indirect golang.org/x/time v0.12.0 // indirect
@@ -97,6 +97,7 @@ require (
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.2 // indirect
k8s.io/api v0.35.1 // indirect k8s.io/api v0.35.1 // indirect
k8s.io/apiextensions-apiserver v0.35.1 // indirect k8s.io/apiextensions-apiserver v0.35.1 // indirect
k8s.io/apimachinery v0.35.1 // indirect k8s.io/apimachinery v0.35.1 // indirect
+20 -23
View File
@@ -43,8 +43,8 @@ github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU= github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v29.2.1+incompatible h1:n3Jt0QVCN65eiVBoUTZQM9mcQICCJt3akW4pKAbKdJg= github.com/docker/cli v29.3.0+incompatible h1:z3iWveU7h19Pqx7alZES8j+IeFQZ1lhTwb2F+V9SVvk=
github.com/docker/cli v29.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v29.3.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
@@ -107,8 +107,8 @@ github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnL
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.21.2 h1:vYaMU4nU55JJGFC9JR/s8NZcTjbE9DBBbvusTW9NeS0= github.com/google/go-containerregistry v0.21.3 h1:Xr+yt3VvwOOn/5nJzd7UoOhwPGiPkYW0zWDLLUXqAi4=
github.com/google/go-containerregistry v0.21.2/go.mod h1:ctO5aCaewH4AK1AumSF5DPW+0+R+d2FmylMJdp5G7p0= github.com/google/go-containerregistry v0.21.3/go.mod h1:D5ZrJF1e6dMzvInpBPuMCX0FxURz7GLq2rV3Us9aPkc=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
@@ -149,8 +149,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.37 h1:3DOZp4cXis1cUIpCfXLtmlGolNLp2VEqhiB/PARNBIg= github.com/mattn/go-sqlite3 v1.14.38 h1:tDUzL85kMvOrvpCt8P64SbGgVFtJB11GPi2AdmITgb4=
github.com/mattn/go-sqlite3 v1.14.37/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.38/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -181,8 +181,6 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -210,8 +208,8 @@ github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDc
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
@@ -305,26 +303,25 @@ go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U=
go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
@@ -345,8 +342,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
helm.sh/helm/v4 v4.1.3 h1:Abfmb+oJUtxoaXDyB2Jhw1zRk3hT6aFfHta+AXb8Lno= helm.sh/helm/v4 v4.1.3 h1:Abfmb+oJUtxoaXDyB2Jhw1zRk3hT6aFfHta+AXb8Lno=
helm.sh/helm/v4 v4.1.3/go.mod h1:5dSo8rRgn3OTkDAc/k0Ipw5/Q+BlqKIKZwa0XwSiINI= helm.sh/helm/v4 v4.1.3/go.mod h1:5dSo8rRgn3OTkDAc/k0Ipw5/Q+BlqKIKZwa0XwSiINI=
k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q= k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q=
+2 -4
View File
@@ -1,8 +1,6 @@
/* /*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com> * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
* */
*
*/
package repocli package repocli
-1
View File
@@ -27,7 +27,6 @@ func TestPushImage(t *testing.T) {
err := load.Push(ctx, "test-oci", "localhost:1025/test:v1.0", "", "") err := load.Push(ctx, "test-oci", "localhost:1025/test:v1.0", "", "")
require.NoError(t, err) require.NoError(t, err)
} }
//return
{ {
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
+5 -3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.24
package configfile package configfile
import ( import (
@@ -6,6 +9,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -374,9 +378,7 @@ func getConfiguredCredentialStore(c *ConfigFile, registryHostname string) string
func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig, error) { func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig, error) {
auths := make(map[string]types.AuthConfig) auths := make(map[string]types.AuthConfig)
addAll := func(from map[string]types.AuthConfig) { addAll := func(from map[string]types.AuthConfig) {
for reg, ac := range from { maps.Copy(auths, from)
auths[reg] = ac
}
} }
defaultStore := configFile.GetCredentialsStore("") defaultStore := configFile.GetCredentialsStore("")
+1 -1
View File
@@ -20,6 +20,6 @@ import "path/filepath"
type Path string type Path string
func (l Path) path(elem ...string) string { func (l Path) path(elem ...string) string {
complete := []string{string(l)} complete := []string{string(l)} //nolint:prealloc
return filepath.Join(append(complete, elem...)...) return filepath.Join(append(complete, elem...)...)
} }
+23
View File
@@ -296,6 +296,29 @@ func extract(img v1.Image, w io.Writer) error {
// Some tools prepend everything with "./", so if we don't Clean the // Some tools prepend everything with "./", so if we don't Clean the
// name, we may have duplicate entries, which angers tar-split. // name, we may have duplicate entries, which angers tar-split.
header.Name = filepath.Clean(header.Name) header.Name = filepath.Clean(header.Name)
// Normalize absolute paths to relative to prevent writing outside
// the extraction root (Zip Slip / CVE-2018-15664 class).
// Many OCI tools emit absolute paths; stripping the leading slash
// preserves the entry while removing the danger.
if filepath.IsAbs(header.Name) {
header.Name = strings.TrimLeft(header.Name, "/")
}
// After normalization, reject any remaining path traversal.
if strings.HasPrefix(header.Name, "..") {
continue
}
// Reject symlinks and hardlinks that point outside the extraction
// root. An attacker can create a symlink to /etc and then write
// files through it in a subsequent layer entry.
if header.Typeflag == tar.TypeSymlink || header.Typeflag == tar.TypeLink {
linkTarget := filepath.Clean(header.Linkname)
if strings.HasPrefix(linkTarget, "..") || filepath.IsAbs(linkTarget) {
continue
}
}
// force PAX format to remove Name/Linkname length limit of 100 characters // force PAX format to remove Name/Linkname length limit of 100 characters
// required by USTAR and to not depend on internal tar package guess which // required by USTAR and to not depend on internal tar package guess which
// prefers USTAR over PAX // prefers USTAR over PAX
+10 -1
View File
@@ -219,6 +219,15 @@ type tarFile struct {
} }
func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) { func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {
return followLinks(opener, filePath, make(map[string]bool))
}
func followLinks(opener Opener, filePath string, visited map[string]bool) (io.ReadCloser, error) {
if visited[filePath] {
return nil, fmt.Errorf("link cycle detected for %s", filePath)
}
visited[filePath] = true
f, err := opener() f, err := opener()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -242,7 +251,7 @@ func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {
if hdr.Name == filePath { if hdr.Name == filePath {
if hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink { if hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink {
currentDir := filepath.Dir(filePath) currentDir := filepath.Dir(filePath)
return extractFileFromTar(opener, path.Join(currentDir, path.Clean(hdr.Linkname))) return followLinks(opener, path.Join(currentDir, path.Clean(hdr.Linkname)), visited)
} }
needClose = false needClose = false
return tarFile{ return tarFile{
+8 -6
View File
@@ -875,7 +875,7 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []driver.Named
// consume the number of arguments used in the current // consume the number of arguments used in the current
// statement and append all named arguments not // statement and append all named arguments not
// contained therein // contained therein
if len(args[start:start+na]) > 0 { if na > 0 {
stmtArgs = append(stmtArgs, args[start:start+na]...) stmtArgs = append(stmtArgs, args[start:start+na]...)
for i := range args { for i := range args {
if (i < start || i >= na) && args[i].Name != "" { if (i < start || i >= na) && args[i].Name != "" {
@@ -1968,7 +1968,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
bindIndices := make([][3]int, len(args)) bindIndices := make([][3]int, len(args))
prefixes := []string{":", "@", "$"} prefixes := []string{":", "@", "$"}
for i, v := range args { for i, v := range args {
bindIndices[i][0] = args[i].Ordinal bindIndices[i][0] = v.Ordinal
if v.Name != "" { if v.Name != "" {
for j := range prefixes { for j := range prefixes {
cname := C.CString(prefixes[j] + v.Name) cname := C.CString(prefixes[j] + v.Name)
@@ -2179,7 +2179,7 @@ func (rc *SQLiteRows) Columns() []string {
defer rc.s.mu.Unlock() defer rc.s.mu.Unlock()
if rc.s.s != nil && int(rc.nc) != len(rc.cols) { if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
rc.cols = make([]string, rc.nc) rc.cols = make([]string, rc.nc)
for i := 0; i < int(rc.nc); i++ { for i := range rc.cols {
rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i))) rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i)))
} }
} }
@@ -2189,7 +2189,7 @@ func (rc *SQLiteRows) Columns() []string {
func (rc *SQLiteRows) declTypes() []string { func (rc *SQLiteRows) declTypes() []string {
if rc.s.s != nil && rc.decltype == nil { if rc.s.s != nil && rc.decltype == nil {
rc.decltype = make([]string, rc.nc) rc.decltype = make([]string, rc.nc)
for i := 0; i < int(rc.nc); i++ { for i := range rc.decltype {
rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
} }
} }
@@ -2251,11 +2251,13 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error {
rc.declTypes() rc.declTypes()
decltype := rc.decltype
_ = decltype[len(dest)-1]
for i := range dest { for i := range dest {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) { switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
case C.SQLITE_INTEGER: case C.SQLITE_INTEGER:
val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
switch rc.decltype[i] { switch decltype[i] {
case columnTimestamp, columnDatetime, columnDate: case columnTimestamp, columnDatetime, columnDate:
var t time.Time var t time.Time
// Assume a millisecond unix timestamp if it's 13 digits -- too // Assume a millisecond unix timestamp if it's 13 digits -- too
@@ -2295,7 +2297,7 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error {
n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n)) s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n))
switch rc.decltype[i] { switch decltype[i] {
case columnTimestamp, columnDatetime, columnDate: case columnTimestamp, columnDatetime, columnDate:
var t time.Time var t time.Time
s = strings.TrimSuffix(s, "Z") s = strings.TrimSuffix(s, "Z")
+12 -4
View File
@@ -301,10 +301,18 @@ const (
OpLT = 16 OpLT = 16
OpGE = 32 OpGE = 32
OpMATCH = 64 OpMATCH = 64
OpLIKE = 65 /* 3.10.0 and later only */ OpLIKE = 65 /* 3.10.0 and later only */
OpGLOB = 66 /* 3.10.0 and later only */ OpGLOB = 66 /* 3.10.0 and later only */
OpREGEXP = 67 /* 3.10.0 and later only */ OpREGEXP = 67 /* 3.10.0 and later only */
OpScanUnique = 1 /* Scan visits at most 1 row */ OpNE = 68 /* 3.21.0 and later only */
OpISNOT = 69 /* 3.21.0 and later */
OpISNOTNULL = 70 /* 3.21.0 and later */
OpISNULL = 71 /* 3.21.0 and later */
OpIS = 72 /* 3.21.0 and later */
OpLIMIT = 73 /* 3.38.0 and later */
OpOFFSET = 74 /* 3.38.0 and later */
OpFUNCTION = 150 /* 3.25.0 and later */
OpScanUnique = 1 /* Scan visits at most 1 row */
) )
// InfoConstraint give information of constraint. // InfoConstraint give information of constraint.
+61 -34
View File
@@ -1,40 +1,67 @@
version: "2"
run: run:
# do not run on test files yet
tests: false tests: false
# all available settings of specific linters
linters-settings:
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
lll:
line-length: 100
tab-width: 4
prealloc:
simple: false
range-loops: false
for-loops: false
whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
linters: linters:
enable: enable:
- megacheck - asasalint
- govet - asciicheck
- bidichk
- bodyclose
- contextcheck
- durationcheck
- errchkjson
- errorlint
- exhaustive
- gocheckcompilerdirectives
- gochecksumtype
- gosec
- gosmopolitan
- loggercheck
- makezero
- musttag
- nilerr
- nilnesserr
- noctx
- protogetter
- reassign
- recvcheck
- rowserrcheck
- spancheck
- sqlclosecheck
- testifylint
- unparam
- zerologlint
disable: disable:
- maligned
- prealloc - prealloc
disable-all: false settings:
presets: errcheck:
- bugs check-type-assertions: false
- unused check-blank: false
fast: false lll:
line-length: 100
tab-width: 4
prealloc:
simple: false
range-loops: false
for-loops: false
whitespace:
multi-if: false
multi-func: false
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
+2 -2
View File
@@ -37,7 +37,7 @@ Features:
# 1.6.0 # 1.6.0
Fixes: Fixes:
* end of line cleanup * end of line cleanup
* revert the entry concurrency bug fix whic leads to deadlock under some circumstances * revert the entry concurrency bug fix which leads to deadlock under some circumstances
* update dependency on go-windows-terminal-sequences to fix a crash with go 1.14 * update dependency on go-windows-terminal-sequences to fix a crash with go 1.14
Features: Features:
@@ -129,7 +129,7 @@ This new release introduces:
which is mostly useful for logger wrapper which is mostly useful for logger wrapper
* a fix reverting the immutability of the entry given as parameter to the hooks * a fix reverting the immutability of the entry given as parameter to the hooks
a new configuration field of the json formatter in order to put all the fields a new configuration field of the json formatter in order to put all the fields
in a nested dictionnary in a nested dictionary
* a new SetOutput method in the Logger * a new SetOutput method in the Logger
* a new configuration of the textformatter to configure the name of the default keys * a new configuration of the textformatter to configure the name of the default keys
* a new configuration of the text formatter to disable the level truncation * a new configuration of the text formatter to disable the level truncation
+64 -60
View File
@@ -1,4 +1,4 @@
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [![Build Status](https://github.com/sirupsen/logrus/workflows/CI/badge.svg)](https://github.com/sirupsen/logrus/actions?query=workflow%3ACI) [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![Go Reference](https://pkg.go.dev/badge/github.com/sirupsen/logrus.svg)](https://pkg.go.dev/github.com/sirupsen/logrus) # Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [![Build Status](https://github.com/sirupsen/logrus/workflows/CI/badge.svg)](https://github.com/sirupsen/logrus/actions?query=workflow%3ACI) [![Go Reference](https://pkg.go.dev/badge/github.com/sirupsen/logrus.svg)](https://pkg.go.dev/github.com/sirupsen/logrus)
Logrus is a structured logger for Go (golang), completely API compatible with Logrus is a structured logger for Go (golang), completely API compatible with
the standard library logger. the standard library logger.
@@ -40,7 +40,7 @@ plain text):
![Colored](http://i.imgur.com/PY7qMwd.png) ![Colored](http://i.imgur.com/PY7qMwd.png)
With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash With `logrus.SetFormatter(&logrus.JSONFormatter{})`, for easy parsing by logstash
or Splunk: or Splunk:
```text ```text
@@ -60,9 +60,9 @@ ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} "time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
``` ```
With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not With the default `logrus.SetFormatter(&logrus.TextFormatter{})` when a TTY is not
attached, the output is compatible with the attached, the output is compatible with the
[logfmt](http://godoc.org/github.com/kr/logfmt) format: [logfmt](https://pkg.go.dev/github.com/kr/logfmt) format:
```text ```text
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
@@ -75,17 +75,18 @@ time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x20822
To ensure this behaviour even if a TTY is attached, set your formatter as follows: To ensure this behaviour even if a TTY is attached, set your formatter as follows:
```go ```go
log.SetFormatter(&log.TextFormatter{ logrus.SetFormatter(&logrus.TextFormatter{
DisableColors: true, DisableColors: true,
FullTimestamp: true, FullTimestamp: true,
}) })
``` ```
#### Logging Method Name #### Logging Method Name
If you wish to add the calling method as a field, instruct the logger via: If you wish to add the calling method as a field, instruct the logger via:
```go ```go
log.SetReportCaller(true) logrus.SetReportCaller(true)
``` ```
This adds the caller as 'method' like so: This adds the caller as 'method' like so:
@@ -100,11 +101,11 @@ time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcr
Note that this does add measurable overhead - the cost will depend on the version of Go, but is Note that this does add measurable overhead - the cost will depend on the version of Go, but is
between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your
environment via benchmarks: environment via benchmarks:
```
```bash
go test -bench=.*CallerTracing go test -bench=.*CallerTracing
``` ```
#### Case-sensitivity #### Case-sensitivity
The organization's name was changed to lower-case--and this will not be changed The organization's name was changed to lower-case--and this will not be changed
@@ -118,12 +119,10 @@ The simplest way to use Logrus is simply the package-level exported logger:
```go ```go
package main package main
import ( import "github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
)
func main() { func main() {
log.WithFields(log.Fields{ logrus.WithFields(logrus.Fields{
"animal": "walrus", "animal": "walrus",
}).Info("A walrus appears") }).Info("A walrus appears")
} }
@@ -139,6 +138,7 @@ package main
import ( import (
"os" "os"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -190,26 +190,27 @@ package main
import ( import (
"os" "os"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// Create a new instance of the logger. You can have any number of instances. // Create a new instance of the logger. You can have any number of instances.
var log = logrus.New() var logger = logrus.New()
func main() { func main() {
// The API for setting attributes is a little different than the package level // The API for setting attributes is a little different than the package level
// exported logger. See Godoc. // exported logger. See Godoc.
log.Out = os.Stdout logger.Out = os.Stdout
// You could set this to any `io.Writer` such as a file // You could set this to any `io.Writer` such as a file
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
// if err == nil { // if err == nil {
// log.Out = file // logger.Out = file
// } else { // } else {
// log.Info("Failed to log to file, using default stderr") // logger.Info("Failed to log to file, using default stderr")
// } // }
log.WithFields(logrus.Fields{ logger.WithFields(logrus.Fields{
"animal": "walrus", "animal": "walrus",
"size": 10, "size": 10,
}).Info("A group of walrus emerges from the ocean") }).Info("A group of walrus emerges from the ocean")
@@ -219,12 +220,12 @@ func main() {
#### Fields #### Fields
Logrus encourages careful, structured logging through logging fields instead of Logrus encourages careful, structured logging through logging fields instead of
long, unparseable error messages. For example, instead of: `log.Fatalf("Failed long, unparseable error messages. For example, instead of: `logrus.Fatalf("Failed
to send event %s to topic %s with key %d")`, you should log the much more to send event %s to topic %s with key %d")`, you should log the much more
discoverable: discoverable:
```go ```go
log.WithFields(log.Fields{ logrus.WithFields(logrus.Fields{
"event": event, "event": event,
"topic": topic, "topic": topic,
"key": key, "key": key,
@@ -245,12 +246,12 @@ seen as a hint you should add a field, however, you can still use the
Often it's helpful to have fields _always_ attached to log statements in an Often it's helpful to have fields _always_ attached to log statements in an
application or parts of one. For example, you may want to always log the application or parts of one. For example, you may want to always log the
`request_id` and `user_ip` in the context of a request. Instead of writing `request_id` and `user_ip` in the context of a request. Instead of writing
`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on `logger.WithFields(logrus.Fields{"request_id": request_id, "user_ip": user_ip})` on
every line, you can create a `logrus.Entry` to pass around instead: every line, you can create a `logrus.Entry` to pass around instead:
```go ```go
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}) requestLogger := logger.WithFields(logrus.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Info("something happened on that request") # will log request_id and user_ip requestLogger.Info("something happened on that request") // will log request_id and user_ip
requestLogger.Warn("something not great happened") requestLogger.Warn("something not great happened")
``` ```
@@ -264,28 +265,31 @@ Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
`init`: `init`:
```go ```go
package main
import ( import (
log "github.com/sirupsen/logrus"
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
"log/syslog" "log/syslog"
"github.com/sirupsen/logrus"
airbrake "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
) )
func init() { func init() {
// Use the Airbrake hook to report errors that have Error severity or above to // Use the Airbrake hook to report errors that have Error severity or above to
// an exception tracker. You can create custom hooks, see the Hooks section. // an exception tracker. You can create custom hooks, see the Hooks section.
log.AddHook(airbrake.NewHook(123, "xyz", "production")) logrus.AddHook(airbrake.NewHook(123, "xyz", "production"))
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
if err != nil { if err != nil {
log.Error("Unable to connect to local syslog daemon") logrus.Error("Unable to connect to local syslog daemon")
} else { } else {
log.AddHook(hook) logrus.AddHook(hook)
} }
} }
``` ```
Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). Note: Syslog hooks also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
@@ -295,15 +299,15 @@ A list of currently known service hooks can be found in this wiki [page](https:/
Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic. Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.
```go ```go
log.Trace("Something very low level.") logrus.Trace("Something very low level.")
log.Debug("Useful debugging information.") logrus.Debug("Useful debugging information.")
log.Info("Something noteworthy happened!") logrus.Info("Something noteworthy happened!")
log.Warn("You should probably take a look at this.") logrus.Warn("You should probably take a look at this.")
log.Error("Something failed but I'm not quitting.") logrus.Error("Something failed but I'm not quitting.")
// Calls os.Exit(1) after logging // Calls os.Exit(1) after logging
log.Fatal("Bye.") logrus.Fatal("Bye.")
// Calls panic() after logging // Calls panic() after logging
log.Panic("I'm bailing.") logrus.Panic("I'm bailing.")
``` ```
You can set the logging level on a `Logger`, then it will only log entries with You can set the logging level on a `Logger`, then it will only log entries with
@@ -311,13 +315,13 @@ that severity or anything above it:
```go ```go
// Will log anything that is info or above (warn, error, fatal, panic). Default. // Will log anything that is info or above (warn, error, fatal, panic). Default.
log.SetLevel(log.InfoLevel) logrus.SetLevel(logrus.InfoLevel)
``` ```
It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose It may be useful to set `logrus.Level = logrus.DebugLevel` in a debug or verbose
environment if your application has that. environment if your application has that.
Note: If you want different log levels for global (`log.SetLevel(...)`) and syslog logging, please check the [syslog hook README](hooks/syslog/README.md#different-log-levels-for-local-and-remote-logging). Note: If you want different log levels for global (`logrus.SetLevel(...)`) and syslog logging, please check the [syslog hook README](hooks/syslog/README.md#different-log-levels-for-local-and-remote-logging).
#### Entries #### Entries
@@ -340,17 +344,17 @@ could do:
```go ```go
import ( import (
log "github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func init() { func init() {
// do something here to set environment depending on an environment variable // do something here to set environment depending on an environment variable
// or command-line flag // or command-line flag
if Environment == "production" { if Environment == "production" {
log.SetFormatter(&log.JSONFormatter{}) logrus.SetFormatter(&logrus.JSONFormatter{})
} else { } else {
// The TextFormatter is default, you don't actually have to do this. // The TextFormatter is default, you don't actually have to do this.
log.SetFormatter(&log.TextFormatter{}) logrus.SetFormatter(&logrus.TextFormatter{})
} }
} }
``` ```
@@ -372,11 +376,11 @@ The built-in logging formatters are:
* When colors are enabled, levels are truncated to 4 characters by default. To disable * When colors are enabled, levels are truncated to 4 characters by default. To disable
truncation set the `DisableLevelTruncation` field to `true`. truncation set the `DisableLevelTruncation` field to `true`.
* When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text. * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). * All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter).
* `logrus.JSONFormatter`. Logs fields as JSON. * `logrus.JSONFormatter`. Logs fields as JSON.
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). * All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter).
Third party logging formatters: Third-party logging formatters:
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine. * [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html). * [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
@@ -384,7 +388,7 @@ Third party logging formatters:
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. * [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo. * [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo.
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. * [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Sava log to files. * [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Save log to files.
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added. * [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
You can define your formatter by implementing the `Formatter` interface, You can define your formatter by implementing the `Formatter` interface,
@@ -393,10 +397,9 @@ requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
default ones (see Entries section above): default ones (see Entries section above):
```go ```go
type MyJSONFormatter struct { type MyJSONFormatter struct{}
}
log.SetFormatter(new(MyJSONFormatter)) logrus.SetFormatter(new(MyJSONFormatter))
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
// Note this doesn't include Time, Level and Message which are available on // Note this doesn't include Time, Level and Message which are available on
@@ -455,17 +458,18 @@ entries. It should not be a feature of the application-level logger.
#### Testing #### Testing
Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: Logrus has a built-in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook * decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
```go ```go
import( import(
"testing"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test" "github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"testing"
) )
func TestSomething(t*testing.T){ func TestSomething(t*testing.T){
@@ -486,15 +490,15 @@ func TestSomething(t*testing.T){
Logrus can register one or more functions that will be called when any `fatal` Logrus can register one or more functions that will be called when any `fatal`
level message is logged. The registered handlers will be executed before level message is logged. The registered handlers will be executed before
logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need
to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. to gracefully shut down. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
``` ```go
... // ...
handler := func() { handler := func() {
// gracefully shutdown something... // gracefully shut down something...
} }
logrus.RegisterExitHandler(handler) logrus.RegisterExitHandler(handler)
... // ...
``` ```
#### Thread safety #### Thread safety
@@ -502,7 +506,7 @@ logrus.RegisterExitHandler(handler)
By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs. By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking. If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
Situation when locking is not needed includes: Situations when locking is not needed include:
* You have no hooks registered, or hooks calling is already thread-safe. * You have no hooks registered, or hooks calling is already thread-safe.
+7 -9
View File
@@ -1,14 +1,12 @@
version: "{build}" # Minimal stub to satisfy AppVeyor CI
version: 1.0.{build}
platform: x64 platform: x64
clone_folder: c:\gopath\src\github.com\sirupsen\logrus shallow_clone: true
environment:
GOPATH: c:\gopath
branches: branches:
only: only:
- master - master
install: - main
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
- go version
build_script: build_script:
- go get -t - echo "No-op build to satisfy AppVeyor CI"
- go test
+14 -11
View File
@@ -34,13 +34,15 @@ func init() {
minimumCallerDepth = 1 minimumCallerDepth = 1
} }
// Defines the key when adding errors using WithError. // ErrorKey defines the key when adding errors using [WithError], [Logger.WithError].
var ErrorKey = "error" var ErrorKey = "error"
// An entry is the final or intermediate Logrus logging entry. It contains all // Entry is the final or intermediate Logrus logging entry. It contains all
// the fields passed with WithField{,s}. It's finally logged when Trace, Debug, // the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
// Info, Warn, Error, Fatal or Panic is called on it. These objects can be // Info, Warn, Error, Fatal or Panic is called on it. These objects can be
// reused and passed around as much as you wish to avoid field duplication. // reused and passed around as much as you wish to avoid field duplication.
//
//nolint:recvcheck // the methods of "Entry" use pointer receiver and non-pointer receiver.
type Entry struct { type Entry struct {
Logger *Logger Logger *Logger
@@ -86,12 +88,12 @@ func (entry *Entry) Dup() *Entry {
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err} return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err}
} }
// Returns the bytes representation of this entry from the formatter. // Bytes returns the bytes representation of this entry from the formatter.
func (entry *Entry) Bytes() ([]byte, error) { func (entry *Entry) Bytes() ([]byte, error) {
return entry.Logger.Formatter.Format(entry) return entry.Logger.Formatter.Format(entry)
} }
// Returns the string representation from the reader and ultimately the // String returns the string representation from the reader and ultimately the
// formatter. // formatter.
func (entry *Entry) String() (string, error) { func (entry *Entry) String() (string, error) {
serialized, err := entry.Bytes() serialized, err := entry.Bytes()
@@ -102,12 +104,13 @@ func (entry *Entry) String() (string, error) {
return str, nil return str, nil
} }
// Add an error as single field (using the key defined in ErrorKey) to the Entry. // WithError adds an error as single field (using the key defined in [ErrorKey])
// to the Entry.
func (entry *Entry) WithError(err error) *Entry { func (entry *Entry) WithError(err error) *Entry {
return entry.WithField(ErrorKey, err) return entry.WithField(ErrorKey, err)
} }
// Add a context to the Entry. // WithContext adds a context to the Entry.
func (entry *Entry) WithContext(ctx context.Context) *Entry { func (entry *Entry) WithContext(ctx context.Context) *Entry {
dataCopy := make(Fields, len(entry.Data)) dataCopy := make(Fields, len(entry.Data))
for k, v := range entry.Data { for k, v := range entry.Data {
@@ -116,12 +119,12 @@ func (entry *Entry) WithContext(ctx context.Context) *Entry {
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx} return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx}
} }
// Add a single field to the Entry. // WithField adds a single field to the Entry.
func (entry *Entry) WithField(key string, value interface{}) *Entry { func (entry *Entry) WithField(key string, value interface{}) *Entry {
return entry.WithFields(Fields{key: value}) return entry.WithFields(Fields{key: value})
} }
// Add a map of fields to the Entry. // WithFields adds a map of fields to the Entry.
func (entry *Entry) WithFields(fields Fields) *Entry { func (entry *Entry) WithFields(fields Fields) *Entry {
data := make(Fields, len(entry.Data)+len(fields)) data := make(Fields, len(entry.Data)+len(fields))
for k, v := range entry.Data { for k, v := range entry.Data {
@@ -150,7 +153,7 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context} return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
} }
// Overrides the time of the Entry. // WithTime overrides the time of the Entry.
func (entry *Entry) WithTime(t time.Time) *Entry { func (entry *Entry) WithTime(t time.Time) *Entry {
dataCopy := make(Fields, len(entry.Data)) dataCopy := make(Fields, len(entry.Data))
for k, v := range entry.Data { for k, v := range entry.Data {
@@ -204,7 +207,7 @@ func getCaller() *runtime.Frame {
// If the caller isn't part of this package, we're done // If the caller isn't part of this package, we're done
if pkg != logrusPackage { if pkg != logrusPackage {
return &f //nolint:scopelint return &f
} }
} }
@@ -432,7 +435,7 @@ func (entry *Entry) Panicln(args ...interface{}) {
entry.Logln(PanicLevel, args...) entry.Logln(PanicLevel, args...)
} }
// Sprintlnn => Sprint no newline. This is to get the behavior of how // sprintlnn => Sprint no newline. This is to get the behavior of how
// fmt.Sprintln where spaces are always added between operands, regardless of // fmt.Sprintln where spaces are always added between operands, regardless of
// their type. Instead of vendoring the Sprintln implementation to spare a // their type. Instead of vendoring the Sprintln implementation to spare a
// string allocation, we do the simplest thing. // string allocation, we do the simplest thing.
+4 -4
View File
@@ -1,16 +1,16 @@
package logrus package logrus
// A hook to be fired when logging on the logging levels returned from // Hook describes hooks to be fired when logging on the logging levels returned from
// `Levels()` on your implementation of the interface. Note that this is not // [Hook.Levels] on your implementation of the interface. Note that this is not
// fired in a goroutine or a channel with workers, you should handle such // fired in a goroutine or a channel with workers, you should handle such
// functionality yourself if your call is non-blocking and you don't wish for // functionality yourself if your call is non-blocking, and you don't wish for
// the logging calls for levels returned from `Levels()` to block. // the logging calls for levels returned from `Levels()` to block.
type Hook interface { type Hook interface {
Levels() []Level Levels() []Level
Fire(*Entry) error Fire(*Entry) error
} }
// Internal type for storing the hooks on a logger instance. // LevelHooks is an internal type for storing the hooks on a logger instance.
type LevelHooks map[Level][]Hook type LevelHooks map[Level][]Hook
// Add a hook to an instance of logger. This is called with // Add a hook to an instance of logger. This is called with
+17 -17
View File
@@ -72,16 +72,16 @@ func (mw *MutexWrap) Disable() {
mw.disabled = true mw.disabled = true
} }
// Creates a new logger. Configuration should be set by changing `Formatter`, // New Creates a new logger. Configuration should be set by changing [Formatter],
// `Out` and `Hooks` directly on the default logger instance. You can also just // Out and Hooks directly on the default Logger instance. You can also just
// instantiate your own: // instantiate your own:
// //
// var log = &logrus.Logger{ // var log = &logrus.Logger{
// Out: os.Stderr, // Out: os.Stderr,
// Formatter: new(logrus.TextFormatter), // Formatter: new(logrus.TextFormatter),
// Hooks: make(logrus.LevelHooks), // Hooks: make(logrus.LevelHooks),
// Level: logrus.DebugLevel, // Level: logrus.DebugLevel,
// } // }
// //
// It's recommended to make this a global instance called `log`. // It's recommended to make this a global instance called `log`.
func New() *Logger { func New() *Logger {
@@ -118,30 +118,30 @@ func (logger *Logger) WithField(key string, value interface{}) *Entry {
return entry.WithField(key, value) return entry.WithField(key, value)
} }
// Adds a struct of fields to the log entry. All it does is call `WithField` for // WithFields adds a struct of fields to the log entry. It calls [Entry.WithField]
// each `Field`. // for each Field.
func (logger *Logger) WithFields(fields Fields) *Entry { func (logger *Logger) WithFields(fields Fields) *Entry {
entry := logger.newEntry() entry := logger.newEntry()
defer logger.releaseEntry(entry) defer logger.releaseEntry(entry)
return entry.WithFields(fields) return entry.WithFields(fields)
} }
// Add an error as single field to the log entry. All it does is call // WithError adds an error as single field to the log entry. It calls
// `WithError` for the given `error`. // [Entry.WithError] for the given error.
func (logger *Logger) WithError(err error) *Entry { func (logger *Logger) WithError(err error) *Entry {
entry := logger.newEntry() entry := logger.newEntry()
defer logger.releaseEntry(entry) defer logger.releaseEntry(entry)
return entry.WithError(err) return entry.WithError(err)
} }
// Add a context to the log entry. // WithContext add a context to the log entry.
func (logger *Logger) WithContext(ctx context.Context) *Entry { func (logger *Logger) WithContext(ctx context.Context) *Entry {
entry := logger.newEntry() entry := logger.newEntry()
defer logger.releaseEntry(entry) defer logger.releaseEntry(entry)
return entry.WithContext(ctx) return entry.WithContext(ctx)
} }
// Overrides the time of the log entry. // WithTime overrides the time of the log entry.
func (logger *Logger) WithTime(t time.Time) *Entry { func (logger *Logger) WithTime(t time.Time) *Entry {
entry := logger.newEntry() entry := logger.newEntry()
defer logger.releaseEntry(entry) defer logger.releaseEntry(entry)
@@ -347,9 +347,9 @@ func (logger *Logger) Exit(code int) {
logger.ExitFunc(code) logger.ExitFunc(code)
} }
//When file is opened with appending mode, it's safe to // SetNoLock disables the lock for situations where a file is opened with
//write concurrently to a file (within 4k message on Linux). // appending mode, and safe for concurrent writes to the file (within 4k
//In these cases user can choose to disable the lock. // message on Linux). In these cases user can choose to disable the lock.
func (logger *Logger) SetNoLock() { func (logger *Logger) SetNoLock() {
logger.mu.Disable() logger.mu.Disable()
} }
+12 -8
View File
@@ -6,13 +6,15 @@ import (
"strings" "strings"
) )
// Fields type, used to pass to `WithFields`. // Fields type, used to pass to [WithFields].
type Fields map[string]interface{} type Fields map[string]interface{}
// Level type // Level type
//
//nolint:recvcheck // the methods of "Entry" use pointer receiver and non-pointer receiver.
type Level uint32 type Level uint32
// Convert the Level to a string. E.g. PanicLevel becomes "panic". // Convert the Level to a string. E.g. [PanicLevel] becomes "panic".
func (level Level) String() string { func (level Level) String() string {
if b, err := level.MarshalText(); err == nil { if b, err := level.MarshalText(); err == nil {
return string(b) return string(b)
@@ -77,7 +79,7 @@ func (level Level) MarshalText() ([]byte, error) {
return nil, fmt.Errorf("not a valid logrus level %d", level) return nil, fmt.Errorf("not a valid logrus level %d", level)
} }
// A constant exposing all logging levels // AllLevels exposing all logging levels.
var AllLevels = []Level{ var AllLevels = []Level{
PanicLevel, PanicLevel,
FatalLevel, FatalLevel,
@@ -119,8 +121,8 @@ var (
) )
// StdLogger is what your logrus-enabled library should take, that way // StdLogger is what your logrus-enabled library should take, that way
// it'll accept a stdlib logger and a logrus logger. There's no standard // it'll accept a stdlib logger ([log.Logger]) and a logrus logger.
// interface, this is the closest we get, unfortunately. // There's no standard interface, so this is the closest we get, unfortunately.
type StdLogger interface { type StdLogger interface {
Print(...interface{}) Print(...interface{})
Printf(string, ...interface{}) Printf(string, ...interface{})
@@ -135,7 +137,8 @@ type StdLogger interface {
Panicln(...interface{}) Panicln(...interface{})
} }
// The FieldLogger interface generalizes the Entry and Logger types // FieldLogger extends the [StdLogger] interface, generalizing
// the [Entry] and [Logger] types.
type FieldLogger interface { type FieldLogger interface {
WithField(key string, value interface{}) *Entry WithField(key string, value interface{}) *Entry
WithFields(fields Fields) *Entry WithFields(fields Fields) *Entry
@@ -176,8 +179,9 @@ type FieldLogger interface {
// IsPanicEnabled() bool // IsPanicEnabled() bool
} }
// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is // Ext1FieldLogger (the first extension to [FieldLogger]) is superfluous, it is
// here for consistancy. Do not use. Use Logger or Entry instead. // here for consistency. Do not use. Use [FieldLogger], [Logger] or [Entry]
// instead.
type Ext1FieldLogger interface { type Ext1FieldLogger interface {
FieldLogger FieldLogger
Tracef(format string, args ...interface{}) Tracef(format string, args ...interface{})
+1 -1
View File
@@ -1,4 +1,4 @@
// +build darwin dragonfly freebsd netbsd openbsd // +build darwin dragonfly freebsd netbsd openbsd hurd
// +build !js // +build !js
package logrus package logrus
+2
View File
@@ -1,5 +1,7 @@
//go:build (linux || aix || zos) && !js && !wasi
// +build linux aix zos // +build linux aix zos
// +build !js // +build !js
// +build !wasi
package logrus package logrus
+8
View File
@@ -0,0 +1,8 @@
//go:build wasi
// +build wasi
package logrus
func isTerminal(fd int) bool {
return false
}
+8
View File
@@ -0,0 +1,8 @@
//go:build wasip1
// +build wasip1
package logrus
func isTerminal(fd int) bool {
return false
}
+2 -1
View File
@@ -306,6 +306,7 @@ func (f *TextFormatter) needsQuoting(text string) bool {
return false return false
} }
for _, ch := range text { for _, ch := range text {
//nolint:staticcheck // QF1001: could apply De Morgan's law
if !((ch >= 'a' && ch <= 'z') || if !((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9') || (ch >= '0' && ch <= '9') ||
@@ -334,6 +335,6 @@ func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
if !f.needsQuoting(stringVal) { if !f.needsQuoting(stringVal) {
b.WriteString(stringVal) b.WriteString(stringVal)
} else { } else {
b.WriteString(fmt.Sprintf("%q", stringVal)) fmt.Fprintf(b, "%q", stringVal)
} }
} }
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && arm64 && gc
#include "textflag.h"
TEXT libc_sysctlbyname_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sysctlbyname(SB)
GLOBL ·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctlbyname_trampoline_addr(SB)/8, $libc_sysctlbyname_trampoline<>(SB)
+3 -6
View File
@@ -44,14 +44,11 @@ func initOptions() {
} }
func archInit() { func archInit() {
switch runtime.GOOS { if runtime.GOOS == "freebsd" {
case "freebsd":
readARM64Registers() readARM64Registers()
case "linux", "netbsd", "openbsd", "windows": } else {
// Most platforms don't seem to allow directly reading these registers.
doinit() doinit()
default:
// Many platforms don't seem to allow reading these registers.
setMinimalFeatures()
} }
} }
+67
View File
@@ -0,0 +1,67 @@
// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && arm64 && gc
package cpu
func doinit() {
setMinimalFeatures()
// The feature flags are explained in [Instruction Set Detection].
// There are some differences between MacOS versions:
//
// MacOS 11 and 12 do not have "hw.optional" sysctl values for some of the features.
//
// MacOS 13 changed some of the naming conventions to align with ARM Architecture Reference Manual.
// For example "hw.optional.armv8_2_sha512" became "hw.optional.arm.FEAT_SHA512".
// It currently checks both to stay compatible with MacOS 11 and 12.
// The old names also work with MacOS 13, however it's not clear whether
// they will continue working with future OS releases.
//
// Once MacOS 12 is no longer supported the old names can be removed.
//
// [Instruction Set Detection]: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
// Encryption, hashing and checksum capabilities
// For the following flags there are no MacOS 11 sysctl flags.
ARM64.HasAES = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_AES\x00"))
ARM64.HasPMULL = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_PMULL\x00"))
ARM64.HasSHA1 = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA1\x00"))
ARM64.HasSHA2 = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA256\x00"))
ARM64.HasSHA3 = darwinSysctlEnabled([]byte("hw.optional.armv8_2_sha3\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA3\x00"))
ARM64.HasSHA512 = darwinSysctlEnabled([]byte("hw.optional.armv8_2_sha512\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA512\x00"))
ARM64.HasCRC32 = darwinSysctlEnabled([]byte("hw.optional.armv8_crc32\x00"))
// Atomic and memory ordering
ARM64.HasATOMICS = darwinSysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_LSE\x00"))
ARM64.HasLRCPC = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_LRCPC\x00"))
// SIMD and floating point capabilities
ARM64.HasFPHP = darwinSysctlEnabled([]byte("hw.optional.neon_fp16\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_FP16\x00"))
ARM64.HasASIMDHP = darwinSysctlEnabled([]byte("hw.optional.neon_hpfp\x00")) || darwinSysctlEnabled([]byte("hw.optional.AdvSIMD_HPFPCvt\x00"))
ARM64.HasASIMDRDM = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_RDM\x00"))
ARM64.HasASIMDDP = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_DotProd\x00"))
ARM64.HasASIMDFHM = darwinSysctlEnabled([]byte("hw.optional.armv8_2_fhm\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_FHM\x00"))
ARM64.HasI8MM = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_I8MM\x00"))
ARM64.HasJSCVT = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_JSCVT\x00"))
ARM64.HasFCMA = darwinSysctlEnabled([]byte("hw.optional.armv8_3_compnum\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_FCMA\x00"))
// Miscellaneous
ARM64.HasDCPOP = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_DPB\x00"))
ARM64.HasEVTSTRM = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_ECV\x00"))
ARM64.HasDIT = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_DIT\x00"))
// Not supported, but added for completeness
ARM64.HasCPUID = false
ARM64.HasSM3 = false // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SM3\x00"))
ARM64.HasSM4 = false // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SM4\x00"))
ARM64.HasSVE = false // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SVE\x00"))
ARM64.HasSVE2 = false // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SVE2\x00"))
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && arm64 && !gc
package cpu
func doinit() {
setMinimalFeatures()
ARM64.HasASIMD = true
ARM64.HasFP = true
// Go already assumes these to be available because they were on the M1
// and these are supported on all Apple arm64 chips.
ARM64.HasAES = true
ARM64.HasPMULL = true
ARM64.HasSHA1 = true
ARM64.HasSHA2 = true
if runtime.GOOS != "ios" {
// Apple A7 processors do not support these, however
// M-series SoCs are at least armv8.4-a
ARM64.HasCRC32 = true // armv8.1
ARM64.HasATOMICS = true // armv8.2
ARM64.HasJSCVT = true // armv8.3, if HasFP
}
}
+1
View File
@@ -9,3 +9,4 @@ package cpu
func getisar0() uint64 { return 0 } func getisar0() uint64 { return 0 }
func getisar1() uint64 { return 0 } func getisar1() uint64 { return 0 }
func getpfr0() uint64 { return 0 } func getpfr0() uint64 { return 0 }
func getzfr0() uint64 { return 0 }
+4 -2
View File
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !linux && !netbsd && !openbsd && !windows && arm64 //go:build !darwin && !linux && !netbsd && !openbsd && !windows && arm64
package cpu package cpu
func doinit() {} func doinit() {
setMinimalFeatures()
}
+54
View File
@@ -0,0 +1,54 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Minimal copy from internal/cpu and runtime to make sysctl calls.
//go:build darwin && arm64 && gc
package cpu
import (
"syscall"
"unsafe"
)
type Errno = syscall.Errno
// adapted from internal/cpu/cpu_arm64_darwin.go
func darwinSysctlEnabled(name []byte) bool {
out := int32(0)
nout := unsafe.Sizeof(out)
if ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); ret != nil {
return false
}
return out > 0
}
//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
var libc_sysctlbyname_trampoline_addr uintptr
// adapted from runtime/sys_darwin.go in the pattern of sysctl() above, as defined in x/sys/unix
func sysctlbyname(name *byte, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error {
if _, _, err := syscall_syscall6(
libc_sysctlbyname_trampoline_addr,
uintptr(unsafe.Pointer(name)),
uintptr(unsafe.Pointer(old)),
uintptr(unsafe.Pointer(oldlen)),
uintptr(unsafe.Pointer(new)),
uintptr(newlen),
0,
); err != 0 {
return err
}
return nil
}
//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname "/usr/lib/libSystem.B.dylib"
// Implemented in the runtime package (runtime/sys_darwin.go)
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
//go:linkname syscall_syscall6 syscall.syscall6
+1 -7
View File
@@ -19,13 +19,7 @@ import (
// A Note is a string describing a process note. // A Note is a string describing a process note.
// It implements the os.Signal interface. // It implements the os.Signal interface.
type Note string type Note = syscall.Note
func (n Note) Signal() {}
func (n Note) String() string {
return string(n)
}
var ( var (
Stdin = 0 Stdin = 0
+125 -104
View File
@@ -593,110 +593,115 @@ const (
) )
const ( const (
NDA_UNSPEC = 0x0 NDA_UNSPEC = 0x0
NDA_DST = 0x1 NDA_DST = 0x1
NDA_LLADDR = 0x2 NDA_LLADDR = 0x2
NDA_CACHEINFO = 0x3 NDA_CACHEINFO = 0x3
NDA_PROBES = 0x4 NDA_PROBES = 0x4
NDA_VLAN = 0x5 NDA_VLAN = 0x5
NDA_PORT = 0x6 NDA_PORT = 0x6
NDA_VNI = 0x7 NDA_VNI = 0x7
NDA_IFINDEX = 0x8 NDA_IFINDEX = 0x8
NDA_MASTER = 0x9 NDA_MASTER = 0x9
NDA_LINK_NETNSID = 0xa NDA_LINK_NETNSID = 0xa
NDA_SRC_VNI = 0xb NDA_SRC_VNI = 0xb
NTF_USE = 0x1 NTF_USE = 0x1
NTF_SELF = 0x2 NTF_SELF = 0x2
NTF_MASTER = 0x4 NTF_MASTER = 0x4
NTF_PROXY = 0x8 NTF_PROXY = 0x8
NTF_EXT_LEARNED = 0x10 NTF_EXT_LEARNED = 0x10
NTF_OFFLOADED = 0x20 NTF_OFFLOADED = 0x20
NTF_ROUTER = 0x80 NTF_ROUTER = 0x80
NUD_INCOMPLETE = 0x1 NUD_INCOMPLETE = 0x1
NUD_REACHABLE = 0x2 NUD_REACHABLE = 0x2
NUD_STALE = 0x4 NUD_STALE = 0x4
NUD_DELAY = 0x8 NUD_DELAY = 0x8
NUD_PROBE = 0x10 NUD_PROBE = 0x10
NUD_FAILED = 0x20 NUD_FAILED = 0x20
NUD_NOARP = 0x40 NUD_NOARP = 0x40
NUD_PERMANENT = 0x80 NUD_PERMANENT = 0x80
NUD_NONE = 0x0 NUD_NONE = 0x0
IFA_UNSPEC = 0x0 IFA_UNSPEC = 0x0
IFA_ADDRESS = 0x1 IFA_ADDRESS = 0x1
IFA_LOCAL = 0x2 IFA_LOCAL = 0x2
IFA_LABEL = 0x3 IFA_LABEL = 0x3
IFA_BROADCAST = 0x4 IFA_BROADCAST = 0x4
IFA_ANYCAST = 0x5 IFA_ANYCAST = 0x5
IFA_CACHEINFO = 0x6 IFA_CACHEINFO = 0x6
IFA_MULTICAST = 0x7 IFA_MULTICAST = 0x7
IFA_FLAGS = 0x8 IFA_FLAGS = 0x8
IFA_RT_PRIORITY = 0x9 IFA_RT_PRIORITY = 0x9
IFA_TARGET_NETNSID = 0xa IFA_TARGET_NETNSID = 0xa
IFAL_LABEL = 0x2 IFAL_LABEL = 0x2
IFAL_ADDRESS = 0x1 IFAL_ADDRESS = 0x1
RT_SCOPE_UNIVERSE = 0x0 RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8 RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd RT_SCOPE_LINK = 0xfd
RT_SCOPE_HOST = 0xfe RT_SCOPE_HOST = 0xfe
RT_SCOPE_NOWHERE = 0xff RT_SCOPE_NOWHERE = 0xff
RT_TABLE_UNSPEC = 0x0 RT_TABLE_UNSPEC = 0x0
RT_TABLE_COMPAT = 0xfc RT_TABLE_COMPAT = 0xfc
RT_TABLE_DEFAULT = 0xfd RT_TABLE_DEFAULT = 0xfd
RT_TABLE_MAIN = 0xfe RT_TABLE_MAIN = 0xfe
RT_TABLE_LOCAL = 0xff RT_TABLE_LOCAL = 0xff
RT_TABLE_MAX = 0xffffffff RT_TABLE_MAX = 0xffffffff
RTA_UNSPEC = 0x0 RTA_UNSPEC = 0x0
RTA_DST = 0x1 RTA_DST = 0x1
RTA_SRC = 0x2 RTA_SRC = 0x2
RTA_IIF = 0x3 RTA_IIF = 0x3
RTA_OIF = 0x4 RTA_OIF = 0x4
RTA_GATEWAY = 0x5 RTA_GATEWAY = 0x5
RTA_PRIORITY = 0x6 RTA_PRIORITY = 0x6
RTA_PREFSRC = 0x7 RTA_PREFSRC = 0x7
RTA_METRICS = 0x8 RTA_METRICS = 0x8
RTA_MULTIPATH = 0x9 RTA_MULTIPATH = 0x9
RTA_FLOW = 0xb RTA_FLOW = 0xb
RTA_CACHEINFO = 0xc RTA_CACHEINFO = 0xc
RTA_TABLE = 0xf RTA_TABLE = 0xf
RTA_MARK = 0x10 RTA_MARK = 0x10
RTA_MFC_STATS = 0x11 RTA_MFC_STATS = 0x11
RTA_VIA = 0x12 RTA_VIA = 0x12
RTA_NEWDST = 0x13 RTA_NEWDST = 0x13
RTA_PREF = 0x14 RTA_PREF = 0x14
RTA_ENCAP_TYPE = 0x15 RTA_ENCAP_TYPE = 0x15
RTA_ENCAP = 0x16 RTA_ENCAP = 0x16
RTA_EXPIRES = 0x17 RTA_EXPIRES = 0x17
RTA_PAD = 0x18 RTA_PAD = 0x18
RTA_UID = 0x19 RTA_UID = 0x19
RTA_TTL_PROPAGATE = 0x1a RTA_TTL_PROPAGATE = 0x1a
RTA_IP_PROTO = 0x1b RTA_IP_PROTO = 0x1b
RTA_SPORT = 0x1c RTA_SPORT = 0x1c
RTA_DPORT = 0x1d RTA_DPORT = 0x1d
RTN_UNSPEC = 0x0 RTN_UNSPEC = 0x0
RTN_UNICAST = 0x1 RTN_UNICAST = 0x1
RTN_LOCAL = 0x2 RTN_LOCAL = 0x2
RTN_BROADCAST = 0x3 RTN_BROADCAST = 0x3
RTN_ANYCAST = 0x4 RTN_ANYCAST = 0x4
RTN_MULTICAST = 0x5 RTN_MULTICAST = 0x5
RTN_BLACKHOLE = 0x6 RTN_BLACKHOLE = 0x6
RTN_UNREACHABLE = 0x7 RTN_UNREACHABLE = 0x7
RTN_PROHIBIT = 0x8 RTN_PROHIBIT = 0x8
RTN_THROW = 0x9 RTN_THROW = 0x9
RTN_NAT = 0xa RTN_NAT = 0xa
RTN_XRESOLVE = 0xb RTN_XRESOLVE = 0xb
SizeofNlMsghdr = 0x10 PREFIX_UNSPEC = 0x0
SizeofNlMsgerr = 0x14 PREFIX_ADDRESS = 0x1
SizeofRtGenmsg = 0x1 PREFIX_CACHEINFO = 0x2
SizeofNlAttr = 0x4 SizeofNlMsghdr = 0x10
SizeofRtAttr = 0x4 SizeofNlMsgerr = 0x14
SizeofIfInfomsg = 0x10 SizeofRtGenmsg = 0x1
SizeofIfAddrmsg = 0x8 SizeofNlAttr = 0x4
SizeofIfAddrlblmsg = 0xc SizeofRtAttr = 0x4
SizeofIfaCacheinfo = 0x10 SizeofIfInfomsg = 0x10
SizeofRtMsg = 0xc SizeofPrefixmsg = 0xc
SizeofRtNexthop = 0x8 SizeofPrefixCacheinfo = 0x8
SizeofNdUseroptmsg = 0x10 SizeofIfAddrmsg = 0x8
SizeofNdMsg = 0xc SizeofIfAddrlblmsg = 0xc
SizeofIfaCacheinfo = 0x10
SizeofRtMsg = 0xc
SizeofRtNexthop = 0x8
SizeofNdUseroptmsg = 0x10
SizeofNdMsg = 0xc
) )
type NlMsghdr struct { type NlMsghdr struct {
@@ -735,6 +740,22 @@ type IfInfomsg struct {
Change uint32 Change uint32
} }
type Prefixmsg struct {
Family uint8
Pad1 uint8
Pad2 uint16
Ifindex int32
Type uint8
Len uint8
Flags uint8
Pad3 uint8
}
type PrefixCacheinfo struct {
Preferred_time uint32
Valid_time uint32
}
type IfAddrmsg struct { type IfAddrmsg struct {
Family uint8 Family uint8
Prefixlen uint8 Prefixlen uint8
+1
View File
@@ -8,5 +8,6 @@ package windows
import "syscall" import "syscall"
type Signal = syscall.Signal
type Errno = syscall.Errno type Errno = syscall.Errno
type SysProcAttr = syscall.SysProcAttr type SysProcAttr = syscall.SysProcAttr
-14
View File
@@ -1490,20 +1490,6 @@ func Getgid() (gid int) { return -1 }
func Getegid() (egid int) { return -1 } func Getegid() (egid int) { return -1 }
func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS } func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS }
type Signal int
func (s Signal) Signal() {}
func (s Signal) String() string {
if 0 <= s && int(s) < len(signals) {
str := signals[s]
if str != "" {
return str
}
}
return "signal " + itoa(int(s))
}
func LoadCreateSymbolicLink() error { func LoadCreateSymbolicLink() error {
return procCreateSymbolicLinkW.Find() return procCreateSymbolicLinkW.Find()
} }
+14 -12
View File
@@ -66,7 +66,7 @@ github.com/cpuguy83/go-md2man/v2/md2man
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit ## explicit
github.com/davecgh/go-spew/spew github.com/davecgh/go-spew/spew
# github.com/docker/cli v29.2.1+incompatible # github.com/docker/cli v29.3.0+incompatible
## explicit ## explicit
github.com/docker/cli/cli/config github.com/docker/cli/cli/config
github.com/docker/cli/cli/config/configfile github.com/docker/cli/cli/config/configfile
@@ -168,8 +168,8 @@ github.com/google/go-cmp/cmp/internal/diff
github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/flags
github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/function
github.com/google/go-cmp/cmp/internal/value github.com/google/go-cmp/cmp/internal/value
# github.com/google/go-containerregistry v0.21.2 # github.com/google/go-containerregistry v0.21.3
## explicit; go 1.25.6 ## explicit; go 1.25.7
github.com/google/go-containerregistry/internal/and github.com/google/go-containerregistry/internal/and
github.com/google/go-containerregistry/internal/compression github.com/google/go-containerregistry/internal/compression
github.com/google/go-containerregistry/internal/estargz github.com/google/go-containerregistry/internal/estargz
@@ -238,7 +238,7 @@ github.com/liggitt/tabwriter
github.com/mailru/easyjson/buffer github.com/mailru/easyjson/buffer
github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jlexer
github.com/mailru/easyjson/jwriter github.com/mailru/easyjson/jwriter
# github.com/mattn/go-sqlite3 v1.14.37 # github.com/mattn/go-sqlite3 v1.14.38
## explicit; go 1.19 ## explicit; go 1.19
github.com/mattn/go-sqlite3 github.com/mattn/go-sqlite3
# github.com/mitchellh/go-homedir v1.1.0 # github.com/mitchellh/go-homedir v1.1.0
@@ -289,8 +289,8 @@ github.com/russross/blackfriday/v2
# github.com/sagikazarmark/locafero v0.11.0 # github.com/sagikazarmark/locafero v0.11.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
github.com/sagikazarmark/locafero github.com/sagikazarmark/locafero
# github.com/sirupsen/logrus v1.9.3 # github.com/sirupsen/logrus v1.9.4
## explicit; go 1.13 ## explicit; go 1.17
github.com/sirupsen/logrus github.com/sirupsen/logrus
# github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 # github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8
## explicit; go 1.20 ## explicit; go 1.20
@@ -412,16 +412,16 @@ golang.org/x/net/http2
golang.org/x/net/http2/hpack golang.org/x/net/http2/hpack
golang.org/x/net/idna golang.org/x/net/idna
golang.org/x/net/internal/httpcommon golang.org/x/net/internal/httpcommon
# golang.org/x/oauth2 v0.35.0 # golang.org/x/oauth2 v0.36.0
## explicit; go 1.24.0 ## explicit; go 1.25.0
golang.org/x/oauth2 golang.org/x/oauth2
golang.org/x/oauth2/internal golang.org/x/oauth2/internal
# golang.org/x/sync v0.19.0 # golang.org/x/sync v0.20.0
## explicit; go 1.24.0 ## explicit; go 1.25.0
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
golang.org/x/sync/semaphore golang.org/x/sync/semaphore
# golang.org/x/sys v0.41.0 # golang.org/x/sys v0.42.0
## explicit; go 1.24.0 ## explicit; go 1.25.0
golang.org/x/sys/cpu golang.org/x/sys/cpu
golang.org/x/sys/plan9 golang.org/x/sys/plan9
golang.org/x/sys/unix golang.org/x/sys/unix
@@ -484,6 +484,8 @@ gopkg.in/inf.v0
# gopkg.in/yaml.v3 v3.0.1 # gopkg.in/yaml.v3 v3.0.1
## explicit ## explicit
gopkg.in/yaml.v3 gopkg.in/yaml.v3
# gotest.tools/v3 v3.5.2
## explicit; go 1.17
# helm.sh/helm/v4 v4.1.3 # helm.sh/helm/v4 v4.1.3
## explicit; go 1.25.0 ## explicit; go 1.25.0
helm.sh/helm/v4/internal/fileutil helm.sh/helm/v4/internal/fileutil