Compare commits

..
Author SHA1 Message Date
sixsmith 4181daac82 run make-i18n 2026-09-29 21:11:56 -04:00
sixsmith 9475381e23 use compose loader for image updates, add shared image test
Look up the service image with the compose loader instead of parsing
the yaml separately, and only rewrite image lines which match it
exactly. Read images back via GetComposeConfig in the tests, drop
testify from them, and add an integration test for pinning services
which use variants of the same image.
2026-09-29 21:11:56 -04:00
sixsmith 7b5c2f4723 run make-i18n 2026-09-29 20:55:40 -04:00
sixsmith 3ba7470a55 fix digest pinning issues in recipe upgrade
Update the image of a single service instead of every service using
the same image name, only rewriting the tag and digest of its image
value so the registry host and the rest of the file are kept as is.

- skip images which use variables, warn to update them manually
- error on images which fail to parse instead of panicking
- drop a stale digest when upgrading a pinned image without
  --pindigests, since it points at the image of the old tag
- error when the registry does not return a digest
- use docker cli credentials when fetching the digest, so private
  registries work after docker login

Add tests for UpdatePinnedTag, UpdateTag and
GetImageMultiplatformDigest.
2026-09-29 20:55:40 -04:00
sixsmith 0f7d991709 add lint rule for images with digest 2026-09-10 00:13:35 -04:00
sixsmith 39050a85ef run make-i18n 2026-09-10 00:13:35 -04:00
sixsmith 92bab8637d add --pindigests flag
* handle digests for the recipe subcommand
* add make parameter to pass args
2026-09-10 00:11:52 -04:00
sixsmith 7932356746 add regclient to fetch image manifest/digest
* also run `go mod vendor`
2026-09-10 00:11:52 -04:00
sixsmith 91fe901264 add docs and test 2026-09-10 00:11:52 -04:00
renovate-bot 5d00b3c932 chore(deps): update golang docker tag 2026-09-08 19:01:07 +00:00
renovate-bot a380b5e8ae chore(deps): update module golang.org/x/term to v0.46.0 2026-09-08 18:03:14 +00:00
renovate-bot 9ff5024a58 chore(deps): update golang docker tag 2026-09-08 15:04:36 +00:00
renovate-bot d6dd082e59 chore(deps): update module golang.org/x/sys to v0.48.0 2026-09-08 14:02:32 +00:00
Weblate 0531f30590 chore: update translation files
Updated by "Update PO files to match POT (msgmerge)" add-on in Weblate.

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/
2026-09-07 14:34:36 +00:00
moritz 27ca0cd21e test(app new): cover a commit that only exists on another branch 2026-09-07 14:34:27 +00:00
moritz 920a898955 fix(git): clone every branch so commits outside the default branch resolve 2026-09-07 14:34:27 +00:00
sixsmith 7cbc974763 chore: mark vendor directory as generated 2026-09-03 05:30:34 +00:00
renovate-bot c71b764546 chore(deps): update otel/weaver docker tag to v0.26.1 2026-09-03 02:01:10 +00:00
renovate-bot 5db8430a73 chore(deps): update nginx docker tag to v1.31.5 2026-09-02 23:01:08 +00:00
renovate-bot 091c4a2ac1 chore(deps): update otel/weaver docker tag to v0.26.0 2026-09-02 19:01:09 +00:00
ChasquiLabo 8e935d08a6 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 22:35:20 +00:00
ChasquiLabo b959c55852 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 21:54:01 +00:00
ChasquiLabo bab9b21882 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 21:42:51 +00:00
ChasquiLabo 703fbf5c8a chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 21:41:22 +00:00
ChasquiLabo aaaf855a6e chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 21:39:07 +00:00
ChasquiLabo a6666be477 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 19:30:19 +00:00
ChasquiLabo ba90b04624 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 19:03:00 +00:00
ChasquiLabo debbdde5d1 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 19:00:21 +00:00
ChasquiLabo 48f62f541f chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 18:56:40 +00:00
ChasquiLabo e6296e4ce4 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 18:53:08 +00:00
ChasquiLabo 423650e8b5 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 18:50:14 +00:00
ChasquiLabo d0c42e37a7 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:56:31 +00:00
ChasquiLabo 6afd17f1ed chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:53:56 +00:00
ChasquiLabo cb0eec2203 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:52:45 +00:00
ChasquiLabo f5900b726b chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:50:52 +00:00
ChasquiLabo 0d9e777c18 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:39:47 +00:00
ChasquiLabo f5cc61c211 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:27:24 +00:00
ChasquiLabo 786ba43b83 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:24:37 +00:00
ChasquiLabo ee80cfa27f chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 16:00:49 +00:00
ChasquiLabo bbaca64d36 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 15:56:33 +00:00
ChasquiLabo b608ee3985 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 15:44:56 +00:00
ChasquiLabo 5e72e28ba6 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 15:37:17 +00:00
ChasquiLabo 84b18c1a7b chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 15:26:49 +00:00
ChasquiLabo 249851a556 chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 14:16:43 +00:00
ChasquiLabo 344b4c8d3d chore: translation using Weblate (Spanish)
Currently translated at 90.6% (1046 of 1154 strings)

Translation: Co-op Cloud/abra
Translate-URL: https://translate.coopcloud.tech/projects/co-op-cloud/abra/es/
2026-09-01 13:12:53 +00:00
70 changed files with 2229 additions and 672 deletions
+1
View File
@@ -0,0 +1 @@
vendor/** linguist-generated=true
+1 -1
View File
@@ -17,7 +17,7 @@ export GOPRIVATE=coopcloud.tech
all: format check build
run:
@go run -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA)
@go run -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA) $(ARGS)
install:
@go install -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA)
+4 -4
View File
@@ -130,7 +130,7 @@ interface.`),
}
for _, service := range config.Services {
img, err := reference.ParseNormalizedNamed(service.Image)
img, err := reference.ParseNormalizedNamed(formatter.RemoveSha(service.Image))
if err != nil {
log.Fatal(err)
}
@@ -298,15 +298,15 @@ interface.`),
var resolvedDigest string
if internal.PinDigests {
digest, dErr := client.GetImageDigest(img, upgradeTag)
digest, dErr := client.GetImageMultiplatformDigest(img, upgradeTag)
if dErr != nil {
log.Fatal(i18n.G("failed to resolve digest for %s:%s: %s", image, upgradeTag, dErr.Error()))
}
resolvedDigest = digest
ok, err = recipe.UpdatePinnedTag(image, upgradeTag, digest)
ok, err = recipe.UpdatePinnedTag(service.Name, upgradeTag, digest)
} else {
ok, err = recipe.UpdateTag(image, upgradeTag)
ok, err = recipe.UpdateTag(service.Name, upgradeTag)
}
if err != nil {
+2 -2
View File
@@ -21,7 +21,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/regclient/regclient v0.11.5
github.com/schollz/progressbar/v3 v3.19.1
golang.org/x/term v0.45.0
golang.org/x/term v0.46.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.2
)
@@ -155,7 +155,7 @@ require (
github.com/stretchr/testify v1.12.1
github.com/theupdateframework/notary v0.7.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
golang.org/x/sys v0.47.0
golang.org/x/sys v0.48.0
)
replace github.com/docker/cli v28.4.0+incompatible => git.coopcloud.tech/toolshed/docker-cli v28.5.3-0.20260202112816-30df2d0b3a00+incompatible
+4 -4
View File
@@ -1148,13 +1148,13 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE=
golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+16 -10
View File
@@ -13,8 +13,6 @@ import (
"github.com/regclient/regclient/types/ref"
)
var rc = regclient.New()
// GetRegistryTags retrieves all tags of an image from a container registry.
func GetRegistryTags(img reference.Named) ([]string, error) {
var tags []string
@@ -35,20 +33,28 @@ func GetRegistryTags(img reference.Named) ([]string, error) {
// GetImageDigest resolves the content digest (sha256:...) for a specific
// image:tag reference by querying the registry manifest. This gives us a
// digest to pin to while keeping support for multi-arch deployments: when
// the tag points at a manifest list/OCI index, the digest returned is the
// digest of that top-level index, so the pin still resolves correctly
// regardless of the deploying host's architecture.
func GetImageDigest(img reference.Named, tag string) (string, error) {
// digest to pin to while keeping support for multi-arch deployments
// See: https://docs.docker.com/build/building/multi-platform/#why-multi-platform-builds
// and: https://docs.docker.com/dhi/explore/security-concepts/digests/#multi-platform-images-and-manifests
func GetImageMultiplatformDigest(img reference.Named, tag string) (string, error) {
r, err := ref.New(fmt.Sprintf("%s:%s", img.Name(), tag))
if err != nil {
return "", fmt.Errorf("parsing reference %s:%s: %w", img.Name(), tag, err)
return "", errors.New(i18n.G("failed to parse image %s:%s, saw: %s", img.Name(), tag, err.Error()))
}
// Use the credentials of the docker cli, which enables using a private
// registry by running docker login on the machine that abra is executed.
rc := regclient.New(regclient.WithDockerCreds())
m, err := rc.ManifestHead(context.Background(), r)
if err != nil {
return "", fmt.Errorf("fetching manifest for %s:%s: %w", img.Name(), tag, err)
return "", errors.New(i18n.G("failed to fetch manifest for %s:%s, saw: %s", img.Name(), tag, err.Error()))
}
return m.GetDescriptor().Digest.String(), nil
digest := m.GetDescriptor().Digest.String()
if digest == "" {
return "", errors.New(i18n.G("registry did not return a digest for %s:%s", img.Name(), tag))
}
return digest, nil
}
+50
View File
@@ -0,0 +1,50 @@
package client
import (
"regexp"
"testing"
"github.com/distribution/reference"
)
func TestGetImageMultiplatformDigest(t *testing.T) {
img, err := reference.ParseNormalizedNamed("nginx")
if err != nil {
t.Fatal(err)
}
digest, err := GetImageMultiplatformDigest(img, "1.21.6")
if err != nil {
t.Fatal(err)
}
if !regexp.MustCompile(`^sha256:[a-f0-9]{64}$`).MatchString(digest) {
t.Fatalf("unexpected digest %s", digest)
}
again, err := GetImageMultiplatformDigest(img, "1.21.6")
if err != nil {
t.Fatal(err)
}
if again != digest {
t.Errorf("got %s on second lookup, want %s", again, digest)
}
other, err := GetImageMultiplatformDigest(img, "1.21.5")
if err != nil {
t.Fatal(err)
}
if other == digest {
t.Errorf("expected different digests for 1.21.5 and 1.21.6, got %s", digest)
}
}
func TestGetImageMultiplatformDigestMissingTag(t *testing.T) {
img, err := reference.ParseNormalizedNamed("nginx")
if err != nil {
t.Fatal(err)
}
if _, err := GetImageMultiplatformDigest(img, "this-tag-does-not-exist"); err == nil {
t.Fatal("expected an error for a missing tag")
}
}
-2
View File
@@ -52,7 +52,6 @@ func Clone(dir, url string) error {
URL: url,
Tags: git.AllTags,
ReferenceName: plumbing.ReferenceName("refs/heads/main"),
SingleBranch: true,
})
if err != nil && gitCloneIgnoreErr(err) {
@@ -71,7 +70,6 @@ func Clone(dir, url string) error {
URL: url,
Tags: git.AllTags,
ReferenceName: plumbing.ReferenceName("refs/heads/master"),
SingleBranch: true,
})
if err != nil && gitCloneIgnoreErr(err) {
+169 -118
View File
@@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-14 17:56+0200\n"
"POT-Creation-Date: 2026-09-29 21:11-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -165,7 +165,7 @@ msgid " # standard rollback\n"
" abra app rollback 1312.net 2.0.0+1.2.3"
msgstr ""
#: ./pkg/formatter/formatter.go:46
#: ./pkg/formatter/formatter.go:47
msgid " ago"
msgstr ""
@@ -189,7 +189,7 @@ msgstr ""
msgid "%d volumes removed successfully"
msgstr ""
#: ./pkg/recipe/git.go:197
#: ./pkg/recipe/git.go:198
#, c-format
msgid "%s (%s) has locally unstaged changes?"
msgstr ""
@@ -219,7 +219,7 @@ msgstr ""
msgid "%s created (version: %s)"
msgstr ""
#: ./cli/recipe/upgrade.go:335
#: ./cli/recipe/upgrade.go:354
#, c-format
msgid "%s currently has these unstaged changes 👇"
msgstr ""
@@ -304,7 +304,7 @@ msgstr ""
msgid "%s has no secrets to generate, skipping..."
msgstr ""
#: ./pkg/recipe/compose.go:107
#: ./pkg/recipe/compose.go:108
#, c-format
msgid "%s has no version label? try running \"abra recipe sync %s\" first?"
msgstr ""
@@ -324,12 +324,12 @@ msgstr ""
msgid "%s is already fetched"
msgstr ""
#: ./pkg/recipe/compose.go:233
#: ./pkg/recipe/compose.go:270
#, c-format
msgid "%s is already set, nothing to do?"
msgstr ""
#: ./pkg/recipe/compose.go:72
#: ./pkg/recipe/compose.go:73
#, c-format
msgid "%s is missing a compose.yml or compose.*.yml file?"
msgstr ""
@@ -419,7 +419,7 @@ msgstr ""
msgid "%s sanitised as %s for new app"
msgstr ""
#: ./pkg/recipe/git.go:445
#: ./pkg/recipe/git.go:451
#, c-format
msgid "%s service is missing image tag?"
msgstr ""
@@ -568,12 +568,12 @@ msgstr ""
msgid "--local detected, running %s on local work station"
msgstr ""
#: ./pkg/lint/recipe.go:261 ./pkg/recipe/files.go:18
#: ./pkg/lint/recipe.go:268 ./pkg/recipe/files.go:18
#, c-format
msgid ".env.sample for %s couldn't be read: %s"
msgstr ""
#: ./pkg/lint/recipe.go:133
#: ./pkg/lint/recipe.go:140
msgid ".env.sample provided"
msgstr ""
@@ -638,17 +638,17 @@ msgstr ""
msgid "CHAOS DEPLOY"
msgstr ""
#: ./pkg/recipe/compose.go:47
#: ./pkg/recipe/compose.go:48
#, c-format
msgid "COMPOSE_FILE (=\"%s\") parsing failed?"
msgstr ""
#: ./pkg/recipe/compose.go:58
#: ./pkg/recipe/compose.go:59
#, c-format
msgid "COMPOSE_FILE detected (%s), loading %s"
msgstr ""
#: ./pkg/recipe/compose.go:38
#: ./pkg/recipe/compose.go:39
#, c-format
msgid "COMPOSE_FILE detected, loading %s"
msgstr ""
@@ -739,7 +739,7 @@ msgid "Create a new version of a recipe.\n"
" ssh-add ~/.ssh/<my-ssh-private-key-for-git-coopcloud-tech>"
msgstr ""
#: ./pkg/formatter/formatter.go:134
#: ./pkg/formatter/formatter.go:135
msgid "CreateOverview: only accepts rows of len == 2"
msgstr ""
@@ -902,7 +902,7 @@ msgstr ""
msgid "Generate the recipe catalogue"
msgstr ""
#: ./pkg/recipe/git.go:459
#: ./pkg/recipe/git.go:465
#, c-format
msgid "GetRecipeVersions encountered error for %s: %s (collected %d versions)"
msgstr ""
@@ -1644,7 +1644,7 @@ msgid "\n"
"\n"
msgstr ""
#: ./pkg/lint/recipe.go:203
#: ./pkg/lint/recipe.go:210
#, c-format
msgid "\n"
"lint %s: %s"
@@ -1687,7 +1687,7 @@ msgctxt "recipe fetch"
msgid "a"
msgstr ""
#: ./cli/recipe/upgrade.go:408
#: ./cli/recipe/upgrade.go:427
msgctxt "recipe upgrade"
msgid "a"
msgstr ""
@@ -1737,7 +1737,7 @@ msgstr ""
msgid "accepts at most 2 args with --local/-l"
msgstr ""
#: ./pkg/recipe/compose.go:249
#: ./pkg/recipe/compose.go:286
#, c-format
msgid "add '- \"%s\"' manually to the 'app' service in %s"
msgstr ""
@@ -1764,11 +1764,15 @@ msgstr ""
msgid "all containers did really go away"
msgstr ""
#: ./pkg/lint/recipe.go:131
msgid "all images use a digest"
msgstr ""
#: ./pkg/lint/recipe.go:82
msgid "all images use a tag"
msgstr ""
#: ./pkg/lint/recipe.go:162
#: ./pkg/lint/recipe.go:169
msgid "all services have images"
msgstr ""
@@ -1780,7 +1784,7 @@ msgstr ""
msgid "all-services"
msgstr ""
#: ./cli/recipe/upgrade.go:407
#: ./cli/recipe/upgrade.go:426
msgid "all-tags"
msgstr ""
@@ -1815,7 +1819,7 @@ msgstr ""
msgid "are you sure?"
msgstr ""
#: ./pkg/recipe/git.go:162
#: ./pkg/recipe/git.go:163
#, c-format
msgid "attempting to checkout '%s' as chaos commit"
msgstr ""
@@ -1919,7 +1923,7 @@ msgstr ""
msgid "c"
msgstr ""
#: ./cli/recipe/upgrade.go:416
#: ./cli/recipe/upgrade.go:435
msgctxt "recipe upgrade"
msgid "c"
msgstr ""
@@ -1928,7 +1932,7 @@ msgstr ""
msgid "can not insert from file and read from stdin"
msgstr ""
#: ./cli/recipe/upgrade.go:323
#: ./cli/recipe/upgrade.go:342
#, c-format
msgid "can upgrade service: %s, image: %s, tag: %s ::"
msgstr ""
@@ -1951,7 +1955,7 @@ msgstr ""
msgid "cancelled"
msgstr ""
#: ./pkg/catalogue/catalogue.go:59 ./pkg/recipe/git.go:251
#: ./pkg/catalogue/catalogue.go:59 ./pkg/recipe/git.go:252
#, c-format
msgid "cannot ensure %s is up-to-date, no git remotes configured"
msgstr ""
@@ -1966,7 +1970,7 @@ msgstr ""
msgid "cannot get label %s for %s"
msgstr ""
#: ./pkg/recipe/git.go:58
#: ./pkg/recipe/git.go:59
#, c-format
msgid "cannot redeploy previous chaos version (%s), did you mean to use \"--chaos\"?"
msgstr ""
@@ -2108,7 +2112,7 @@ msgstr ""
msgid "chore: publish new catalogue release changes"
msgstr ""
#: ./cli/recipe/upgrade.go:352
#: ./cli/recipe/upgrade.go:371
msgid "chore: update image tags"
msgstr ""
@@ -2118,7 +2122,7 @@ msgstr ""
msgid "cmd"
msgstr ""
#: ./pkg/recipe/git.go:470
#: ./pkg/recipe/git.go:476
#, c-format
msgid "collected %s for %s"
msgstr ""
@@ -2170,19 +2174,19 @@ msgstr ""
msgid "commandconn: starting %s with %v"
msgstr ""
#: ./cli/recipe/upgrade.go:415
#: ./cli/recipe/upgrade.go:434
msgid "commit"
msgstr ""
#: ./cli/recipe/upgrade.go:418
#: ./cli/recipe/upgrade.go:437
msgid "commit changes"
msgstr ""
#: ./cli/recipe/upgrade.go:342
#: ./cli/recipe/upgrade.go:361
msgid "commit changes?"
msgstr ""
#: ./cli/recipe/upgrade.go:356
#: ./cli/recipe/upgrade.go:375
#, c-format
msgid "committed changes as '%s'"
msgstr ""
@@ -2221,7 +2225,7 @@ msgstr ""
msgid "config not found: %s"
msgstr ""
#: ./pkg/lint/recipe.go:169
#: ./pkg/lint/recipe.go:176
msgid "config version are vendored"
msgstr ""
@@ -2230,14 +2234,14 @@ msgstr ""
msgid "connection timed out for %s"
msgstr ""
#: ./pkg/recipe/compose.go:191
#: ./pkg/recipe/compose.go:144
#, c-format
msgid "considering %s config(s) for label update"
msgid "considering %s config(s) for image update"
msgstr ""
#: ./pkg/recipe/compose.go:123
#: ./pkg/recipe/compose.go:228
#, c-format
msgid "considering %s config(s) for tag update"
msgid "considering %s config(s) for label update"
msgstr ""
#: ./cli/app/undeploy.go:141 ./cli/server/prune.go:53
@@ -2258,7 +2262,7 @@ msgstr ""
msgid "context lacks Docker endpoint"
msgstr ""
#: ./pkg/recipe/compose.go:229
#: ./pkg/recipe/compose.go:266
#, c-format
msgid "coop-cloud.${STACK_NAME}.version=%s"
msgstr ""
@@ -2303,7 +2307,7 @@ msgstr ""
msgid "create <domain> [flags]"
msgstr ""
#: ./pkg/lint/recipe.go:134
#: ./pkg/lint/recipe.go:141
msgid "create an example .env.sample"
msgstr ""
@@ -2418,7 +2422,7 @@ msgstr ""
msgid "deploy in progress 🟠"
msgstr ""
#: ./pkg/lint/recipe.go:147
#: ./pkg/lint/recipe.go:154
msgid "deploy labels stanza present"
msgstr ""
@@ -2456,12 +2460,12 @@ msgstr ""
msgid "destination directory does not exist"
msgstr ""
#: ./pkg/recipe/git.go:373
#: ./pkg/recipe/git.go:379
#, c-format
msgid "detected %s as tags for recipe %s"
msgstr ""
#: ./pkg/formatter/formatter.go:80
#: ./pkg/formatter/formatter.go:81
msgid "detected ABRA_CI=1"
msgstr ""
@@ -2644,7 +2648,7 @@ msgstr ""
msgid "ensure 'version: \"3.8\"' in compose configs"
msgstr ""
#: ./pkg/lint/recipe.go:163
#: ./pkg/lint/recipe.go:170
msgid "ensure \"image: ...\" set on all services"
msgstr ""
@@ -2653,7 +2657,7 @@ msgstr ""
msgid "ensure recipe: %s"
msgstr ""
#: ./pkg/recipe/git.go:56
#: ./pkg/recipe/git.go:57
#, c-format
msgid "ensuring env version %s"
msgstr ""
@@ -2682,7 +2686,7 @@ msgstr ""
msgid "err: %v, "
msgstr ""
#: ./cli/recipe/lint.go:82 ./cli/recipe/lint.go:144 ./pkg/lint/recipe.go:132 ./pkg/lint/recipe.go:139 ./pkg/lint/recipe.go:146 ./pkg/lint/recipe.go:153 ./pkg/lint/recipe.go:161 ./pkg/lint/recipe.go:168 ./pkg/lint/recipe.go:175
#: ./cli/recipe/lint.go:82 ./cli/recipe/lint.go:144 ./pkg/lint/recipe.go:139 ./pkg/lint/recipe.go:146 ./pkg/lint/recipe.go:153 ./pkg/lint/recipe.go:160 ./pkg/lint/recipe.go:168 ./pkg/lint/recipe.go:175 ./pkg/lint/recipe.go:182
msgid "error"
msgstr ""
@@ -2751,12 +2755,12 @@ msgstr ""
msgid "failed to check git status of %s: %s"
msgstr ""
#: ./pkg/git/branch.go:95 ./pkg/recipe/git.go:231
#: ./pkg/git/branch.go:95 ./pkg/recipe/git.go:232
#, c-format
msgid "failed to check out %s in %s"
msgstr ""
#: ./pkg/recipe/git.go:412
#: ./pkg/recipe/git.go:418
#, c-format
msgid "failed to check out %s in %s: %s"
msgstr ""
@@ -2801,12 +2805,17 @@ msgstr ""
msgid "failed to create volume %s on %s: %s"
msgstr ""
#: ./pkg/client/registry.go:51
#, c-format
msgid "failed to fetch manifest for %s:%s, saw: %s"
msgstr ""
#: ./pkg/secret/secret.go:104
#, c-format
msgid "failed to generate random bytes: %w"
msgstr ""
#: ./pkg/recipe/git.go:421
#: ./pkg/recipe/git.go:427
#, c-format
msgid "failed to get compose config for %s: %s"
msgstr ""
@@ -2839,12 +2848,17 @@ msgstr ""
msgid "failed to migrate app config: %s"
msgstr ""
#: ./pkg/client/registry.go:20
#: ./pkg/client/registry.go:22
#, c-format
msgid "failed to parse image %s, saw: %s"
msgstr ""
#: ./pkg/recipe/git.go:431
#: ./pkg/client/registry.go:42
#, c-format
msgid "failed to parse image %s:%s, saw: %s"
msgstr ""
#: ./pkg/recipe/git.go:437
#, c-format
msgid "failed to parse image for %s in %s: %s"
msgstr ""
@@ -2898,6 +2912,11 @@ msgstr ""
msgid "failed to resize tty, using default size"
msgstr ""
#: ./cli/recipe/upgrade.go:303
#, c-format
msgid "failed to resolve digest for %s:%s: %s"
msgstr ""
#: ./cli/app/new.go:138
#, c-format
msgid "failed to retrieve latest commit for %s: %s"
@@ -2952,7 +2971,7 @@ msgstr ""
msgid "fetch all recipes"
msgstr ""
#: ./pkg/catalogue/catalogue.go:84 ./pkg/recipe/git.go:284
#: ./pkg/catalogue/catalogue.go:84 ./pkg/recipe/git.go:290
#, c-format
msgid "fetched latest git changes for %s"
msgstr ""
@@ -3070,12 +3089,12 @@ msgstr ""
msgid "git changes pushed"
msgstr ""
#: ./pkg/recipe/git.go:417
#: ./pkg/recipe/git.go:423
#, c-format
msgid "git checkout: %s in %s"
msgstr ""
#: ./pkg/git/clone.go:64 ./pkg/git/clone.go:102
#: ./pkg/git/clone.go:63 ./pkg/git/clone.go:100
#, c-format
msgid "git clone %s: cancelled due to interrupt"
msgstr ""
@@ -3085,17 +3104,17 @@ msgstr ""
msgid "git clone: %s"
msgstr ""
#: ./pkg/git/clone.go:89
#: ./pkg/git/clone.go:87
#, c-format
msgid "git clone: %s already exists"
msgstr ""
#: ./pkg/git/clone.go:59 ./pkg/git/clone.go:78 ./pkg/git/clone.go:87
#: ./pkg/git/clone.go:58 ./pkg/git/clone.go:76 ./pkg/git/clone.go:85
#, c-format
msgid "git clone: %s cloned successfully"
msgstr ""
#: ./pkg/git/clone.go:68
#: ./pkg/git/clone.go:67
msgid "git clone: main branch failed, attempting master branch"
msgstr ""
@@ -3150,7 +3169,7 @@ msgstr ""
msgid "git.coopcloud.tech repo exists"
msgstr ""
#: ./pkg/recipe/git.go:384
#: ./pkg/recipe/git.go:390
#, c-format
msgid "git: opening repository in %s"
msgstr ""
@@ -3211,11 +3230,11 @@ msgstr ""
msgid "images pruned: %d; space reclaimed: %s"
msgstr ""
#: ./pkg/lint/recipe.go:148
#: ./pkg/lint/recipe.go:155
msgid "include \"deploy: labels: ...\" stanza"
msgstr ""
#: ./pkg/lint/recipe.go:155
#: ./pkg/lint/recipe.go:162
msgid "include \"traefik.enable=true\" deploy label"
msgstr ""
@@ -3291,15 +3310,15 @@ msgstr ""
msgid "including VOLUMES=%v in backupbot exec invocation"
msgstr ""
#: ./cli/recipe/release.go:634 ./cli/recipe/upgrade.go:378
#: ./cli/recipe/release.go:634 ./cli/recipe/upgrade.go:397
msgid "increase the major part of the version"
msgstr ""
#: ./cli/recipe/release.go:642 ./cli/recipe/upgrade.go:386
#: ./cli/recipe/release.go:642 ./cli/recipe/upgrade.go:405
msgid "increase the minor part of the version"
msgstr ""
#: ./cli/recipe/release.go:650 ./cli/recipe/upgrade.go:394
#: ./cli/recipe/release.go:650 ./cli/recipe/upgrade.go:413
msgid "increase the patch part of the version"
msgstr ""
@@ -3369,7 +3388,7 @@ msgstr ""
msgid "invalid detach escape keys, using default: %s"
msgstr ""
#: ./pkg/lint/recipe.go:504
#: ./pkg/lint/recipe.go:533
msgid "invalid lightweight tag detected"
msgstr ""
@@ -3430,12 +3449,12 @@ msgstr ""
msgid "lint <recipe> [flags]"
msgstr ""
#: ./pkg/lint/recipe.go:187
#: ./pkg/lint/recipe.go:194
#, c-format
msgid "linting for critical errors in %s configs"
msgstr ""
#: ./pkg/lint/recipe.go:215
#: ./pkg/lint/recipe.go:222
#, c-format
msgid "linting successful, %s is well configured"
msgstr ""
@@ -3464,7 +3483,7 @@ msgstr ""
msgid "list [flags]"
msgstr ""
#: ./cli/recipe/upgrade.go:410
#: ./cli/recipe/upgrade.go:429
msgid "list all tags, not just upgrades"
msgstr ""
@@ -3534,11 +3553,11 @@ msgstr ""
#. with no spaces in between
#. translators: `abra man` aliases. use a comma separated list of aliases
#. with no spaces in between
#: ./cli/app/list.go:319 ./cli/app/move.go:34 ./cli/app/ps.go:205 ./cli/app/secret.go:553 ./cli/app/secret.go:649 ./cli/recipe/list.go:104 ./cli/recipe/upgrade.go:400 ./cli/recipe/version.go:139 ./cli/run.go:152 ./cli/server/list.go:106
#: ./cli/app/list.go:319 ./cli/app/move.go:34 ./cli/app/ps.go:205 ./cli/app/secret.go:553 ./cli/app/secret.go:649 ./cli/recipe/list.go:104 ./cli/recipe/upgrade.go:419 ./cli/recipe/version.go:139 ./cli/run.go:152 ./cli/server/list.go:106
msgid "m"
msgstr ""
#: ./cli/app/list.go:318 ./cli/app/ps.go:204 ./cli/app/secret.go:552 ./cli/app/secret.go:648 ./cli/recipe/list.go:103 ./cli/recipe/upgrade.go:399 ./cli/recipe/version.go:138 ./cli/server/list.go:105
#: ./cli/app/list.go:318 ./cli/app/ps.go:204 ./cli/app/secret.go:552 ./cli/app/secret.go:648 ./cli/recipe/list.go:103 ./cli/recipe/upgrade.go:418 ./cli/recipe/version.go:138 ./cli/server/list.go:105
msgid "machine"
msgstr ""
@@ -3547,7 +3566,7 @@ msgstr ""
msgid "main app service version for %s is empty?"
msgstr ""
#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:66 ./cli/internal/recipe.go:80 ./cli/recipe/release.go:631 ./cli/recipe/upgrade.go:375
#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:66 ./cli/internal/recipe.go:80 ./cli/recipe/release.go:631 ./cli/recipe/upgrade.go:394
msgid "major"
msgstr ""
@@ -3576,7 +3595,7 @@ msgstr ""
msgid "migrating app config from %s to %s"
msgstr ""
#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:68 ./cli/internal/recipe.go:82 ./cli/recipe/release.go:639 ./cli/recipe/upgrade.go:383
#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:68 ./cli/internal/recipe.go:82 ./cli/recipe/release.go:639 ./cli/recipe/upgrade.go:402
msgid "minor"
msgstr ""
@@ -3627,7 +3646,7 @@ msgstr ""
msgid "name"
msgstr ""
#: ./pkg/lint/recipe.go:141
#: ./pkg/lint/recipe.go:148
msgid "name a servce 'app'"
msgstr ""
@@ -3705,7 +3724,7 @@ msgstr ""
msgid "no .git directory in %s?"
msgstr ""
#: ./pkg/recipe/compose.go:29
#: ./pkg/recipe/compose.go:30
#, c-format
msgid "no COMPOSE_FILE detected, loading default: %s"
msgstr ""
@@ -3731,7 +3750,7 @@ msgstr ""
msgid "no changes discovered in %s, nothing to publish?"
msgstr ""
#: ./cli/recipe/upgrade.go:361
#: ./cli/recipe/upgrade.go:380
msgid "no changes, skip creating commit"
msgstr ""
@@ -3756,7 +3775,7 @@ msgstr ""
msgid "no domain provided"
msgstr ""
#: ./pkg/recipe/compose.go:248
#: ./pkg/recipe/compose.go:285
msgid "no existing label found, automagic insertion not supported yet"
msgstr ""
@@ -3897,7 +3916,7 @@ msgstr ""
msgid "not requesting a remote TTY"
msgstr ""
#: ./cli/recipe/upgrade.go:305
#: ./cli/recipe/upgrade.go:324
#, c-format
msgid "not upgrading %s, skipping as requested"
msgstr ""
@@ -3928,11 +3947,11 @@ msgstr ""
msgid "one of <src>/<dest> arguments must take $SERVICE:$PATH form"
msgstr ""
#: ./pkg/lint/recipe.go:140
#: ./pkg/lint/recipe.go:147
msgid "one service named 'app'"
msgstr ""
#: ./pkg/lint/recipe.go:176
#: ./pkg/lint/recipe.go:183
msgid "only annotated tags used for recipe version"
msgstr ""
@@ -3956,16 +3975,16 @@ msgstr ""
msgid "p"
msgstr ""
#: ./cli/recipe/upgrade.go:443
msgctxt "pin container image by digest"
msgid "p"
msgstr ""
#: ./cli/recipe/upgrade.go:163
#, c-format
msgid "parsed %s for %s"
msgstr ""
#: ./pkg/recipe/compose.go:159
#, c-format
msgid "parsed %s from %s"
msgstr ""
#: ./cli/app/cmd.go:134 ./cli/app/cmd.go:180
#, c-format
msgid "parsed following command arguments: %s"
@@ -3999,7 +4018,7 @@ msgstr ""
msgid "pass command not found on $PATH, is it installed?"
msgstr ""
#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:70 ./cli/internal/recipe.go:84 ./cli/recipe/release.go:647 ./cli/recipe/upgrade.go:391
#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:70 ./cli/internal/recipe.go:84 ./cli/recipe/release.go:647 ./cli/recipe/upgrade.go:410
msgid "patch"
msgstr ""
@@ -4015,6 +4034,14 @@ msgstr ""
msgid "perform action without further prompt"
msgstr ""
#: ./cli/recipe/upgrade.go:445
msgid "pin the container image version by manifest digest (image:tag@sha256:...)"
msgstr ""
#: ./cli/recipe/upgrade.go:442
msgid "pindigests"
msgstr ""
#. translators: `abra app env pull` aliases. use a comma separated list of
#. aliases with no spaces in between
#: ./cli/app/env.go:39
@@ -4053,7 +4080,7 @@ msgstr ""
msgid "prefer offline & filesystem access"
msgstr ""
#: ./cli/app/list.go:321 ./cli/app/ps.go:207 ./cli/app/secret.go:555 ./cli/app/secret.go:651 ./cli/recipe/list.go:106 ./cli/recipe/upgrade.go:402 ./cli/recipe/version.go:141 ./cli/server/list.go:108
#: ./cli/app/list.go:321 ./cli/app/ps.go:207 ./cli/app/secret.go:555 ./cli/app/secret.go:651 ./cli/recipe/list.go:106 ./cli/recipe/upgrade.go:421 ./cli/recipe/version.go:141 ./cli/server/list.go:108
msgid "print machine-readable output"
msgstr ""
@@ -4061,7 +4088,7 @@ msgstr ""
msgid "proceed?"
msgstr ""
#: ./pkg/recipe/git.go:404
#: ./pkg/recipe/git.go:410
#, c-format
msgid "processing %s for %s"
msgstr ""
@@ -4129,7 +4156,7 @@ msgstr ""
msgid "re"
msgstr ""
#: ./pkg/recipe/git.go:157
#: ./pkg/recipe/git.go:158
#, c-format
msgid "read %s as tags for recipe %s"
msgstr ""
@@ -4206,7 +4233,7 @@ msgstr ""
msgid "recipe %s does not exist?"
msgstr ""
#: ./pkg/lint/recipe.go:212
#: ./pkg/lint/recipe.go:219
#, c-format
msgid "recipe '%s' failed lint checks:\n"
"%s"
@@ -4230,6 +4257,11 @@ msgstr ""
msgid "ref"
msgstr ""
#: ./pkg/client/registry.go:56
#, c-format
msgid "registry did not return a digest for %s:%s"
msgstr ""
#. translators: `recipe release` command
#: ./cli/recipe/release.go:35
msgid "release <recipe> [version] [flags]"
@@ -4328,6 +4360,11 @@ msgstr ""
msgid "removing configs failed: %s"
msgstr ""
#: ./pkg/recipe/compose.go:120
#, c-format
msgid "removing digest from %s for %s, use --pindigests to pin the new tag"
msgstr ""
#: ./pkg/upstream/stack/remove.go:148
#, c-format
msgid "removing network %s"
@@ -4353,7 +4390,7 @@ msgstr ""
msgid "removing volumes failed: %s"
msgstr ""
#: ./pkg/lint/recipe.go:177
#: ./pkg/lint/recipe.go:184
msgid "replace lightweight tag with annotated tag"
msgstr ""
@@ -4436,7 +4473,7 @@ msgstr ""
msgid "retrieved %s as target container on %s"
msgstr ""
#: ./pkg/recipe/compose.go:59
#: ./pkg/recipe/compose.go:60
#, c-format
msgid "retrieved %s configs for %s"
msgstr ""
@@ -4607,7 +4644,7 @@ msgstr ""
msgid "secret %s is > %d chars when combined with %s"
msgstr ""
#: ./pkg/lint/recipe.go:481
#: ./pkg/lint/recipe.go:510
#, c-format
msgid "secret %s is longer than 12 characters"
msgstr ""
@@ -4865,17 +4902,17 @@ msgstr ""
msgid "skipping secret (because it already exists) on %s: %s"
msgstr ""
#: ./pkg/recipe/git.go:413
#: ./pkg/recipe/git.go:419
#, c-format
msgid "skipping tag %s: checkout failed: %s"
msgstr ""
#: ./pkg/recipe/git.go:422
#: ./pkg/recipe/git.go:428
#, c-format
msgid "skipping tag %s: invalid compose config: %s"
msgstr ""
#: ./pkg/recipe/git.go:432
#: ./pkg/recipe/git.go:438
#, c-format
msgid "skipping tag %s: invalid image reference in service %s: %s"
msgstr ""
@@ -4969,7 +5006,7 @@ msgstr ""
msgid "store secrets in a local pass store"
msgstr ""
#: ./pkg/formatter/formatter.go:238
#: ./pkg/formatter/formatter.go:239
#, c-format
msgid "stripped %s to %s for parsing"
msgstr ""
@@ -4978,7 +5015,7 @@ msgstr ""
msgid "succeeded"
msgstr ""
#: ./pkg/recipe/git.go:184
#: ./pkg/recipe/git.go:185
#, c-format
msgid "successfully checked %s out to %s in %s"
msgstr ""
@@ -5007,7 +5044,7 @@ msgstr ""
msgid "sync [flags]"
msgstr ""
#: ./pkg/recipe/compose.go:243
#: ./pkg/recipe/compose.go:280
#, c-format
msgid "synced label %s to service %s"
msgstr ""
@@ -5025,7 +5062,12 @@ msgstr ""
msgid "tag at commit %s is unannotated or otherwise broken"
msgstr ""
#: ./cli/recipe/upgrade.go:301
#: ./cli/recipe/upgrade.go:317
#, c-format
msgid "tag upgraded and pinned from %s to %s@%s for %s"
msgstr ""
#: ./cli/recipe/upgrade.go:319
#, c-format
msgid "tag upgraded from %s to %s for %s"
msgstr ""
@@ -5099,7 +5141,7 @@ msgstr ""
msgid "toggle non-interactive mode"
msgstr ""
#: ./pkg/lint/recipe.go:154
#: ./pkg/lint/recipe.go:161
msgid "traefik routing enabled"
msgstr ""
@@ -5138,17 +5180,17 @@ msgstr ""
msgid "un"
msgstr ""
#: ./pkg/recipe/git.go:193
#: ./pkg/recipe/git.go:194
#, c-format
msgid "unable to check git clean status in %s: %s"
msgstr ""
#: ./pkg/recipe/git.go:262
#: ./pkg/recipe/git.go:263
#, c-format
msgid "unable to check out default branch in %s: %s"
msgstr ""
#: ./pkg/git/clone.go:100
#: ./pkg/git/clone.go:98
#, c-format
msgid "unable to clean up git clone of %s: %s"
msgstr ""
@@ -5222,17 +5264,22 @@ msgstr ""
msgid "unable to discover SSH remote for %s"
msgstr ""
#: ./pkg/recipe/git.go:268
#: ./pkg/recipe/git.go:274
#, c-format
msgid "unable to fetch tags in %s: %s"
msgstr ""
#: ./pkg/recipe/compose.go:181
#, c-format
msgid "unable to find image %s for %s in %s, please update it manually"
msgstr ""
#: ./cli/app/move.go:301
#, c-format
msgid "unable to get container matching %s: %s"
msgstr ""
#: ./pkg/recipe/git.go:280
#: ./pkg/recipe/git.go:286
#, c-format
msgid "unable to git pull in %s: %s"
msgstr ""
@@ -5247,7 +5294,7 @@ msgstr ""
msgid "unable to inspect container for %s: %s"
msgstr ""
#: ./pkg/lint/recipe.go:496
#: ./pkg/lint/recipe.go:525
#, c-format
msgid "unable to list local tags for %s"
msgstr ""
@@ -5261,12 +5308,12 @@ msgstr ""
msgid "unable to look up server context for %s: %s"
msgstr ""
#: ./cli/recipe/fetch.go:77 ./pkg/git/read.go:26 ./pkg/lint/recipe.go:491 ./pkg/recipe/git.go:242
#: ./cli/recipe/fetch.go:77 ./pkg/git/read.go:26 ./pkg/lint/recipe.go:520 ./pkg/recipe/git.go:243
#, c-format
msgid "unable to open %s: %s"
msgstr ""
#: ./pkg/recipe/git.go:257
#: ./pkg/recipe/git.go:258
#, c-format
msgid "unable to open git work tree in %s: %s"
msgstr ""
@@ -5291,11 +5338,6 @@ msgstr ""
msgid "unable to parse %s, error was: %s, skipping upgrade for %s"
msgstr ""
#: ./pkg/recipe/compose.go:153
#, c-format
msgid "unable to parse %s, skipping"
msgstr ""
#: ./cli/app/list.go:167
#, c-format
msgid "unable to parse %s, skipping as upgrade option"
@@ -5311,6 +5353,11 @@ msgstr ""
msgid "unable to parse deploy version: %s"
msgstr ""
#: ./pkg/recipe/compose.go:204
#, c-format
msgid "unable to parse image %s: %s"
msgstr ""
#: ./cli/run.go:176
#, c-format
msgid "unable to proceed, %s does not exist?"
@@ -5326,7 +5373,7 @@ msgstr ""
msgid "unable to read new env %s: %s"
msgstr ""
#: ./pkg/recipe/git.go:247
#: ./pkg/recipe/git.go:248
#, c-format
msgid "unable to read remotes in %s: %s"
msgstr ""
@@ -5361,7 +5408,7 @@ msgstr ""
msgid "unable to reset commit after failed release attempt: %s"
msgstr ""
#: ./pkg/recipe/git.go:166
#: ./pkg/recipe/git.go:167
#, c-format
msgid "unable to resolve '%s': %s"
msgstr ""
@@ -5518,7 +5565,7 @@ msgstr ""
msgid "updating %s"
msgstr ""
#: ./pkg/recipe/compose.go:171 ./pkg/recipe/compose.go:237
#: ./pkg/recipe/compose.go:187 ./pkg/recipe/compose.go:274
#, c-format
msgid "updating %s to %s in %s"
msgstr ""
@@ -5562,6 +5609,10 @@ msgstr ""
msgid "upload your recipe to git.coopcloud.tech/coop-cloud/..."
msgstr ""
#: ./pkg/lint/recipe.go:132
msgid "use a digest for all images"
msgstr ""
#: ./pkg/lint/recipe.go:83
msgid "use a tag for all images"
msgstr ""
@@ -5612,7 +5663,7 @@ msgstr ""
msgid "validated %s as server argument"
msgstr ""
#: ./pkg/lint/recipe.go:170
#: ./pkg/lint/recipe.go:177
msgid "vendor config versions in an abra.sh"
msgstr ""
@@ -5763,7 +5814,7 @@ msgstr ""
msgid "waiting for %d task(s) to reach terminal state"
msgstr ""
#: ./pkg/lint/recipe.go:21 ./pkg/lint/recipe.go:67 ./pkg/lint/recipe.go:74 ./pkg/lint/recipe.go:81 ./pkg/lint/recipe.go:88 ./pkg/lint/recipe.go:95 ./pkg/lint/recipe.go:102 ./pkg/lint/recipe.go:109 ./pkg/lint/recipe.go:116 ./pkg/lint/recipe.go:123
#: ./pkg/lint/recipe.go:21 ./pkg/lint/recipe.go:67 ./pkg/lint/recipe.go:74 ./pkg/lint/recipe.go:81 ./pkg/lint/recipe.go:88 ./pkg/lint/recipe.go:95 ./pkg/lint/recipe.go:102 ./pkg/lint/recipe.go:109 ./pkg/lint/recipe.go:116 ./pkg/lint/recipe.go:123 ./pkg/lint/recipe.go:130
msgid "warn"
msgstr ""
@@ -5806,11 +5857,11 @@ msgstr ""
msgid "writing recipe version failed: %s"
msgstr ""
#: ./cli/recipe/release.go:632 ./cli/recipe/upgrade.go:376
#: ./cli/recipe/release.go:632 ./cli/recipe/upgrade.go:395
msgid "x"
msgstr ""
#: ./cli/recipe/release.go:640 ./cli/recipe/upgrade.go:384
#: ./cli/recipe/release.go:640 ./cli/recipe/upgrade.go:403
msgid "y"
msgstr ""
@@ -5822,7 +5873,7 @@ msgstr ""
msgid "you can only use one version flag: --major, --minor or --patch"
msgstr ""
#: ./cli/recipe/release.go:648 ./cli/recipe/upgrade.go:392
#: ./cli/recipe/release.go:648 ./cli/recipe/upgrade.go:411
msgid "z"
msgstr ""
Binary file not shown.
+805 -348
View File
File diff suppressed because it is too large Load Diff
+29
View File
@@ -125,6 +125,13 @@ var LintRules = map[string][]LintRule{
HowToResolve: i18n.G("reduce length of secret names to 12 chars"),
Function: LintSecretLengths,
},
{
Ref: "R016",
Level: i18n.G("warn"),
Description: i18n.G("all images use a digest"),
HowToResolve: i18n.G("use a digest for all images"),
Function: LintAllImagesTaggedWithDigest,
},
},
"error": {
{
@@ -333,6 +340,28 @@ func LintAllImagesTagged(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintAllImagesTaggedWithDigest(recipe recipe.Recipe) (bool, error) {
config, err := recipe.GetComposeConfig(nil)
if err != nil {
return false, err
}
for _, service := range config.Services {
img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil {
return false, err
}
if reference.IsNameOnly(img) {
return false, nil
}
_, ok := img.(reference.Digested)
if !ok {
return false, nil
}
}
return true, nil
}
func LintNoUnstableTags(recipe recipe.Recipe) (bool, error) {
config, err := recipe.GetComposeConfig(nil)
if err != nil {
+67 -96
View File
@@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"coopcloud.tech/abra/pkg/formatter"
@@ -110,140 +111,110 @@ func (r Recipe) GetVersionLabelLocal() (string, error) {
return label, nil
}
// UpdateTag updates an image tag in-place on file system local compose files.
func (r Recipe) UpdateTag(image, tag string) (bool, error) {
fullPattern := fmt.Sprintf("%s/compose**yml", r.Dir)
image = formatter.StripTagMeta(image)
// UpdateTag updates the image tag of a service in-place on file system local
// compose files. An existing digest is dropped, since it would still point at
// the image of the old tag.
func (r Recipe) UpdateTag(serviceName, tag string) (bool, error) {
return r.updateServiceImage(serviceName, func(image string) (string, error) {
if strings.Contains(image, "@") {
log.Warn(i18n.G("removing digest from %s for %s, use --pindigests to pin the new tag", image, serviceName))
}
return setImageTag(image, tag, "")
})
}
composeFiles, err := filepath.Glob(fullPattern)
// UpdatePinnedTag updates the image of a service to a pinned version
// (image:tag@sha256:...) in-place on file system local compose files.
func (r Recipe) UpdatePinnedTag(serviceName, tag, digest string) (bool, error) {
return r.updateServiceImage(serviceName, func(image string) (string, error) {
return setImageTag(image, tag, digest)
})
}
// updateServiceImage rewrites the image of a service in all local compose
// files which define it. Only image lines matching the current image exactly
// are touched, so other services using a variant of the same image (e.g.
// nginx:1.21.0-alpine) are left as is.
func (r Recipe) updateServiceImage(serviceName string, rewrite func(image string) (string, error)) (bool, error) {
composeFiles, err := filepath.Glob(fmt.Sprintf("%s/compose**yml", r.Dir))
if err != nil {
return false, err
}
log.Debug(i18n.G("considering %s config(s) for tag update", strings.Join(composeFiles, ", ")))
log.Debug(i18n.G("considering %s config(s) for image update", strings.Join(composeFiles, ", ")))
sampleEnv, err := r.SampleEnv()
if err != nil {
return false, err
}
updated := false
for _, composeFile := range composeFiles {
opts := stack.Deploy{Composefiles: []string{composeFile}}
sampleEnv, err := r.SampleEnv()
if err != nil {
return false, err
}
compose, err := loader.LoadComposefile(opts, sampleEnv)
if err != nil {
return false, err
}
for _, service := range compose.Services {
if service.Image == "" {
if service.Name != serviceName || service.Image == "" {
continue // may be a compose.$optional.yml file
}
img, _ := reference.ParseNormalizedNamed(service.Image)
old := service.Image
new, err := rewrite(old)
if err != nil {
return false, err
}
if old == new {
continue
}
bytes, err := os.ReadFile(composeFile)
if err != nil {
return false, err
}
var composeTag string
switch img.(type) {
case reference.NamedTagged:
composeTag = img.(reference.NamedTagged).Tag()
default:
log.Debug(i18n.G("unable to parse %s, skipping", img))
imageLine := regexp.MustCompile(`(?m)^(\s*image:\s*["']?)` + regexp.QuoteMeta(old) + `(["']?\s*(#.*)?)$`)
if !imageLine.Match(bytes) {
// the image is set via a variable, e.g. nginx:${VERSION}
log.Warn(i18n.G("unable to find image %s for %s in %s, please update it manually", old, serviceName, composeFile))
continue
}
composeImage := formatter.StripTagMeta(reference.Path(img))
replacedBytes := imageLine.ReplaceAllString(string(bytes), "${1}"+strings.ReplaceAll(new, "$", "$$")+"${2}")
log.Debug(i18n.G("parsed %s from %s", composeTag, service.Image))
log.Debug(i18n.G("updating %s to %s in %s", old, new, composeFile))
if image == composeImage {
bytes, err := ioutil.ReadFile(composeFile)
if err != nil {
return false, err
}
old := fmt.Sprintf("%s:%s", composeImage, composeTag)
new := fmt.Sprintf("%s:%s", composeImage, tag)
if old == new {
continue
}
replacedBytes := strings.Replace(string(bytes), old, new, -1)
log.Debug(i18n.G("updating %s to %s in %s", old, new, compose.Filename))
if err := os.WriteFile(compose.Filename, []byte(replacedBytes), 0o764); err != nil {
return false, err
}
updated = true
if err := os.WriteFile(composeFile, []byte(replacedBytes), 0o764); err != nil {
return false, err
}
updated = true
}
}
return updated, nil
}
// UpdatePinnedTag updates an image reference to a pinned version (image:tag@sha256:...) in-place on local compose files.
func (r Recipe) UpdatePinnedTag(image, tag, digest string) (bool, error) {
glob := fmt.Sprintf("%s/compose**yml", r.Dir)
image = formatter.StripTagMeta(image)
composeFiles, err := filepath.Glob(glob)
if err != nil {
return false, err
// setImageTag replaces the tag and digest of an image while keeping the image
// name as written (e.g. including the registry host). An empty digest leaves
// the image unpinned.
func setImageTag(image, tag, digest string) (string, error) {
if _, err := reference.ParseNormalizedNamed(image); err != nil {
return "", errors.New(i18n.G("unable to parse image %s: %s", image, err))
}
updated := false
for _, composeFile := range composeFiles {
opts := stack.Deploy{Composefiles: []string{composeFile}}
sampleEnv, err := r.SampleEnv()
if err != nil {
return false, err
}
compose, err := loader.LoadComposefile(opts, sampleEnv)
if err != nil {
return false, err
}
for _, service := range compose.Services {
if service.Image == "" {
continue
}
img, _ := reference.ParseNormalizedNamed(formatter.StripDigest(service.Image))
composeImage := formatter.StripTagMeta(reference.Path(img))
if image == composeImage {
bytes, err := ioutil.ReadFile(composeFile)
if err != nil {
return false, err
}
old := service.Image
new := fmt.Sprintf("%s:%s@%s", composeImage, tag, digest)
if old == new {
continue
}
replacedBytes := strings.Replace(string(bytes), old, new, -1)
log.Debug(i18n.G("updating pinned reference %s to %s in %s", old, new, compose.Filename))
if err := os.WriteFile(compose.Filename, []byte(replacedBytes), 0o764); err != nil {
return false, err
}
updated = true
}
}
name := formatter.RemoveSha(image)
if i := strings.LastIndex(name, ":"); i > strings.LastIndex(name, "/") {
name = name[:i] // strip the tag, but not a registry port
}
return updated, nil
new := fmt.Sprintf("%s:%s", name, tag)
if digest != "" {
new = fmt.Sprintf("%s@%s", new, digest)
}
return new, nil
}
// UpdateLabel updates a label in-place on file system local compose files.
+305
View File
@@ -0,0 +1,305 @@
package recipe
import (
"os"
"path"
"regexp"
"testing"
"coopcloud.tech/abra/pkg/client"
"github.com/distribution/reference"
)
const (
testDigest = "sha256:2bcabc23b45489fb0885d69a06ba1d648aeda973fae7bb981bafbb884165e514"
testNewDigest = "sha256:908dc23e643a1447dbfb2e189ed268bfde6a51a5bf9a34d3dd3440a24f58ccf7"
testAlpineDigest = "sha256:a74534e76ee1121d418fa7394ca930eb67440deda413848bc67c68138535b989"
)
func writeTestRecipe(t *testing.T, compose, sampleEnv string) Recipe {
t.Helper()
dir := t.TempDir()
r := Recipe{
Name: "test_recipe",
Dir: dir,
ComposePath: path.Join(dir, "compose.yml"),
SampleEnvPath: path.Join(dir, ".env.sample"),
}
if err := os.WriteFile(r.ComposePath, []byte(compose), 0o644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(r.SampleEnvPath, []byte("TYPE=test_recipe\n"+sampleEnv), 0o644); err != nil {
t.Fatal(err)
}
return r
}
// composeWithImages returns a compose file with the services "app" and "db"
// using the given images, in that order.
func composeWithImages(images ...string) string {
out := "---\nversion: \"3.8\"\n\nservices:\n"
names := []string{"app", "db"}
for i, image := range images {
out += " " + names[i] + ":\n image: " + image + "\n"
}
return out
}
// serviceImages returns the image of each service, as loaded from the recipe
// compose files.
func serviceImages(t *testing.T, r Recipe) map[string]string {
t.Helper()
config, err := r.GetComposeConfig(nil)
if err != nil {
t.Fatal(err)
}
images := make(map[string]string)
for _, service := range config.Services {
images[service.Name] = service.Image
}
return images
}
func assertImages(t *testing.T, r Recipe, want map[string]string) {
t.Helper()
got := serviceImages(t, r)
if len(got) != len(want) {
t.Fatalf("got services %v, want %v", got, want)
}
for service, image := range want {
if got[service] != image {
t.Errorf("service %s: got image %s, want %s", service, got[service], image)
}
}
}
func TestUpdatePinnedTag(t *testing.T) {
tests := []struct {
name string
images []string
sampleEnv string
service string
tag string
digest string
wantUpdated bool
wantImages map[string]string
}{
{
name: "pin unpinned image",
images: []string{"nginx:1.21.0"},
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "nginx:1.21.6@" + testDigest},
},
{
name: "pin same tag",
images: []string{"nginx:1.21.6"},
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "nginx:1.21.6@" + testDigest},
},
{
name: "replace existing digest",
images: []string{"nginx:1.21.6@" + testDigest},
service: "app",
tag: "1.31.6",
digest: testNewDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "nginx:1.31.6@" + testNewDigest},
},
{
name: "already pinned",
images: []string{"nginx:1.21.6@" + testDigest},
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: false,
wantImages: map[string]string{"app": "nginx:1.21.6@" + testDigest},
},
{
name: "only the given service is pinned",
images: []string{"nginx:1.21.0", "postgres:15"},
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "nginx:1.21.6@" + testDigest, "db": "postgres:15"},
},
{
name: "same image in another service is left alone",
images: []string{"nginx:1.21.0", "nginx:1.21.0-alpine"},
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "nginx:1.21.6@" + testDigest, "db": "nginx:1.21.0-alpine"},
},
{
name: "keep registry host",
images: []string{"ghcr.io/foo/bar:1.0"},
service: "app",
tag: "1.1",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "ghcr.io/foo/bar:1.1@" + testDigest},
},
{
name: "keep registry port",
images: []string{"localhost:5000/foo/bar:1.0"},
service: "app",
tag: "1.1",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "localhost:5000/foo/bar:1.1@" + testDigest},
},
{
name: "quoted image",
images: []string{`"nginx:1.21.0"`},
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: true,
wantImages: map[string]string{"app": "nginx:1.21.6@" + testDigest},
},
{
name: "skip image with variable",
images: []string{"nginx:${NGINX_VERSION}"},
sampleEnv: "NGINX_VERSION=1.21.0\n",
service: "app",
tag: "1.21.6",
digest: testDigest,
wantUpdated: false,
wantImages: map[string]string{"app": "nginx:1.21.0"},
},
{
name: "no matching service",
images: []string{"nginx:1.21.0"},
service: "db",
tag: "1.21.6",
digest: testDigest,
wantUpdated: false,
wantImages: map[string]string{"app": "nginx:1.21.0"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
r := writeTestRecipe(t, composeWithImages(test.images...), test.sampleEnv)
updated, err := r.UpdatePinnedTag(test.service, test.tag, test.digest)
if err != nil {
t.Fatal(err)
}
if updated != test.wantUpdated {
t.Errorf("got updated %v, want %v", updated, test.wantUpdated)
}
assertImages(t, r, test.wantImages)
})
}
}
func TestUpdatePinnedTagInvalidImage(t *testing.T) {
r := writeTestRecipe(t, composeWithImages("Nginx:1.21.0"), "")
if _, err := r.UpdatePinnedTag("app", "1.21.6", testDigest); err == nil {
t.Fatal("expected an error for an invalid image")
}
assertImages(t, r, map[string]string{"app": "Nginx:1.21.0"})
}
func TestUpdateTag(t *testing.T) {
r := writeTestRecipe(t, composeWithImages("nginx:1.21.0", "nginx:1.21.0-alpine"), "")
updated, err := r.UpdateTag("app", "1.21.6")
if err != nil {
t.Fatal(err)
}
if !updated {
t.Error("expected image to be updated")
}
assertImages(t, r, map[string]string{"app": "nginx:1.21.6", "db": "nginx:1.21.0-alpine"})
updated, err = r.UpdateTag("app", "1.21.6")
if err != nil {
t.Fatal(err)
}
if updated {
t.Error("expected no update for the same tag")
}
}
// An existing digest points at the old image, keeping it after a tag
// upgrade would silently deploy the previous version under the new tag.
func TestUpdateTagDropsStaleDigest(t *testing.T) {
r := writeTestRecipe(t, composeWithImages("nginx:1.21.6@"+testDigest), "")
updated, err := r.UpdateTag("app", "1.31.6")
if err != nil {
t.Fatal(err)
}
if !updated {
t.Error("expected image to be updated")
}
assertImages(t, r, map[string]string{"app": "nginx:1.31.6"})
}
// Services using variants of the same image must each be pinned to the
// digest of their own tag, in whichever order they are upgraded.
func TestUpdatePinnedTagSharedImageIntegration(t *testing.T) {
img, err := reference.ParseNormalizedNamed("nginx")
if err != nil {
t.Fatal(err)
}
upgradeTags := map[string]string{"app": "1.21.6", "db": "1.21.6-alpine"}
digests := make(map[string]string)
for service, tag := range upgradeTags {
digest, err := client.GetImageMultiplatformDigest(img, tag)
if err != nil {
t.Fatal(err)
}
if !regexp.MustCompile(`^sha256:[a-f0-9]{64}$`).MatchString(digest) {
t.Fatalf("unexpected digest %s for %s", digest, tag)
}
digests[service] = digest
}
if digests["app"] == digests["db"] {
t.Fatalf("expected different digests for %v, got %s", upgradeTags, digests["app"])
}
for _, order := range [][]string{{"app", "db"}, {"db", "app"}} {
t.Run(order[0]+" first", func(t *testing.T) {
r := writeTestRecipe(t, composeWithImages("nginx:1.21.0", "nginx:1.21.0-alpine"), "")
for _, service := range order {
updated, err := r.UpdatePinnedTag(service, upgradeTags[service], digests[service])
if err != nil {
t.Fatal(err)
}
if !updated {
t.Errorf("expected %s to be updated", service)
}
}
assertImages(t, r, map[string]string{
"app": "nginx:1.21.6@" + digests["app"],
"db": "nginx:1.21.6-alpine@" + digests["db"],
})
})
}
}
+8 -2
View File
@@ -16,6 +16,7 @@ import (
"coopcloud.tech/tagcmp"
"github.com/distribution/reference"
"github.com/go-git/go-git/v5"
gitCfg "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
)
@@ -262,7 +263,12 @@ func (r Recipe) EnsureUpToDate() error {
return errors.New(i18n.G("unable to check out default branch in %s: %s", r.Dir, err))
}
fetchOpts := &git.FetchOptions{Tags: git.AllTags}
// the refspec is passed explicitly, because a repository cloned by an older abra has a
// single-branch refspec stored in its config and would otherwise never see other branches
fetchOpts := &git.FetchOptions{
Tags: git.AllTags,
RefSpecs: []gitCfg.RefSpec{"+refs/heads/*:refs/remotes/origin/*"},
}
if err := repo.Fetch(fetchOpts); err != nil {
if !strings.Contains(err.Error(), "already up-to-date") {
return errors.New(i18n.G("unable to fetch tags in %s: %s", r.Dir, err))
@@ -426,7 +432,7 @@ func (r Recipe) GetRecipeVersions() (RecipeVersions, []string, error) {
versionMeta := make(map[string]ServiceMeta)
for _, service := range config.Services {
img, err := reference.ParseNormalizedNamed(service.Image)
img, err := reference.ParseNormalizedNamed(formatter.RemoveSha(service.Image))
if err != nil {
log.Debug(i18n.G("failed to parse image for %s in %s: %s", service.Name, tag, err))
warnMsg = append(warnMsg, i18n.G("skipping tag %s: invalid image reference in service %s: %s", tag, service.Name, err))
+1 -1
View File
@@ -3,7 +3,7 @@ version: "3.8"
services:
app:
image: nginx:1.31.4
image: nginx:1.31.5
secrets:
- test_pass_one
- test_pass_two
+33
View File
@@ -122,6 +122,39 @@ teardown(){
assert_failure
}
@test "create new app with commit from another branch" {
branchHash=$(_get_other_branch_hash)
if [[ -z "$branchHash" ]]; then
skip "$TEST_RECIPE has no branch besides main"
fi
# re-clone the recipe the way an older abra did, with a single-branch refspec. --no-local
# forces a real transfer, a local clone would hardlink the whole object database and leave
# the commit reachable
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE"
assert_success
run git clone -q --no-local --single-branch --branch main \
"$ABRA_DIR/origin-recipes/$TEST_RECIPE.git" "$ABRA_DIR/recipes/$TEST_RECIPE"
assert_success
# the commit has to be genuinely missing, otherwise this test passes for the wrong reason
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" rev-parse --verify "$branchHash^{commit}"
assert_failure
run $ABRA app new "$TEST_RECIPE" "$branchHash" \
--no-input \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
# the recipe names itself in TYPE, which differs per branch, so only the version is checked
run grep -q "TYPE=.*:${branchHash}$" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success
}
@test "does not overwrite existing env files" {
run $ABRA app new "$TEST_RECIPE" \
--no-input \
+7
View File
@@ -56,6 +56,13 @@ _get_tag_hash() {
echo $(git -C "$ABRA_DIR/recipes/$TEST_RECIPE" rev-list -n 1 "$1")
}
_get_other_branch_hash() {
# asked from the origin mirror, not from the recipe checkout, so that the result does not
# depend on what has been fetched. empty when the recipe only has a default branch
echo $(git ls-remote "$ABRA_DIR/origin-recipes/$TEST_RECIPE.git" \
| grep 'refs/heads/' | grep -v 'refs/heads/main$' | head -1 | cut -f1)
}
_get_head_hash() {
echo $(git -C "$ABRA_DIR/recipes/$TEST_RECIPE" show -s --format="%H" HEAD)
}
+1 -1
View File
@@ -3,7 +3,7 @@ version: "3.8"
services:
app:
image: nginx:1.31.4
image: nginx:1.31.5
networks:
- proxy
deploy:
+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.27@sha256:eb37f58646a901dc7727cf448cae36daaefaba79de33b5058dab79aa4c04aefb
FROM golang:1.27@sha256:512690a5660563b57d37ecc31129e7f136e831db2aed24a1dbeb8ad7380dc0fa
ENV GOOS=linux
ENV GOARCH=arm
+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.27@sha256:eb37f58646a901dc7727cf448cae36daaefaba79de33b5058dab79aa4c04aefb
FROM golang:1.27@sha256:512690a5660563b57d37ecc31129e7f136e831db2aed24a1dbeb8ad7380dc0fa
ENV GOOS=linux
ENV GOARCH=arm64
+15 -6
View File
@@ -182,12 +182,13 @@ var MIPS64X struct {
// require kernel support to work (DARN, SCV), so there are feature bits for
// those as well. The struct is padded to avoid false sharing.
var PPC64 struct {
_ CacheLinePad
HasDARN bool // Hardware random number generator (requires kernel enablement)
HasSCV bool // Syscall vectored (requires kernel enablement)
IsPOWER8 bool // ISA v2.07 (POWER8)
IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
_ CacheLinePad
_ CacheLinePad
HasDARN bool // Hardware random number generator (requires kernel enablement)
HasSCV bool // Syscall vectored (requires kernel enablement)
IsPOWER8 bool // ISA v2.07 (POWER8)
IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
IsPOWER10 bool // ISA v3.1 (POWER10 and POWER11; POWER11 did not add a new architected level), implies IsPOWER9
_ CacheLinePad
}
// S390X contains the supported CPU features of the current IBM Z
@@ -248,13 +249,21 @@ var RISCV64 struct {
HasZvks bool // ShangMi Algorithm Suite
HasZvksc bool // ShangMi Algorithm Suite with carryless multiplication
HasZvksg bool // ShangMi Algorithm Suite with GCM
VLENB uint // Vector register length in bytes, 0 if undetected
_ CacheLinePad
}
// doDerived, if non-nil, is called after processing GODEBUG to set "derived"
// feature flags.
var doDerived func()
func init() {
archInit()
initOptions()
processOptions()
if doDerived != nil {
doDerived()
}
}
// options contains the cpu debug options that can be used in GODEBUG.
+11
View File
@@ -0,0 +1,11 @@
// 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 gc
package cpu
// Can only be called when the vector extension is present.
// Implemented in cpu_riscv64.s.
func readVLENB() uint
+4
View File
@@ -11,6 +11,7 @@ const (
// ISA Level
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
_PPC_FEATURE2_ARCH_3_1 = 0x00040000
// CPU features
_PPC_FEATURE2_DARN = 0x00200000
@@ -21,6 +22,9 @@ func doinit() {
// HWCAP2 feature bits
PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
// ISA 3.1 covers both POWER10 and POWER11: POWER11 did not introduce a
// new architected HWCAP level, so there is no separate IsPOWER11.
PPC64.IsPOWER10 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_1)
PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
}
+11
View File
@@ -130,6 +130,9 @@ func doinit() {
RISCV64.HasFastMisaligned = v == riscv_HWPROBE_MISALIGNED_FAST
}
}
if RISCV64.HasV {
RISCV64.VLENB = readVLENB()
}
// Let's double check with HWCAP if the C extension does not appear to be supported.
// This may happen if we're running on a kernel older than 6.4.
@@ -137,6 +140,14 @@ func doinit() {
if !RISCV64.HasC {
RISCV64.HasC = isSet(hwCap, hwcap_RISCV_ISA_C)
}
doDerived = func() {
// If the vector extension is disabled by GODEBUG, then the VLENB is zero.
if !RISCV64.HasV {
RISCV64.VLENB = 0
}
}
}
func isSet(hwc uint, value uint) bool {
+47
View File
@@ -0,0 +1,47 @@
// 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 netbsd && amd64 && gc
package cpu
func doinit() {
// NetBSD corrupts avx registers when receiving signals.
// See issue 80285.
// TODO: when NetBSD fixes the bug, add a version
// check and skip here.
X86.HasAVX = false
X86.HasAVX2 = false
// Set these also, just to be safe
X86.HasAVXVNNI = false
X86.HasAVX512 = false
X86.HasAVX512F = false
X86.HasAVX512CD = false
X86.HasAVX512CD = false
X86.HasAVX512ER = false
X86.HasAVX512PF = false
X86.HasAVX512VL = false
X86.HasAVX512BW = false
X86.HasAVX512DQ = false
X86.HasAVX512IFMA = false
X86.HasAVX512VBMI = false
X86.HasAVX5124VNNIW = false
X86.HasAVX5124FMAPS = false
X86.HasAVX512VPOPCNTDQ = false
X86.HasAVX512VPCLMULQDQ = false
X86.HasAVX512VNNI = false
X86.HasAVX512GFNI = false
X86.HasAVX512VAES = false
X86.HasAVX512VBMI2 = false
X86.HasAVX512BITALG = false
X86.HasAVX512BF16 = false
X86.HasAVXIFMA = false
X86.HasAVXVNNI = false
X86.HasAVXVNNIInt8 = false
}
func darwinSupportsAVX512() bool {
panic("only implemented for gc && amd64 && darwin")
}
+1 -1
View File
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build 386 || amd64p32 || (amd64 && (!darwin || !gc))
//go:build 386 || amd64p32 || (amd64 && ((!darwin && !netbsd) || !gc))
package cpu
+17
View File
@@ -0,0 +1,17 @@
// 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 gc
#include "textflag.h"
// Read the vector register length in bytes from the vlenb CSR.
// May only be called when the vector extension is present.
// func readVLENB() uint
TEXT ·readVLENB(SB), NOSPLIT|NOFRAME, $0-8
// Go 1.25's assembler does not recognize VLENB, so use its raw CSRR encoding.
// Replace WORD with CSRR VLENB, X10 once go.mod requires Go 1.27.
WORD $0xc2202573
MOV X10, ret+0(FP)
RET
+12
View File
@@ -0,0 +1,12 @@
// 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 sparc64
package cpu
// The L1 line is 32 bytes; false sharing is governed by the 64-byte L2 line.
const cacheLineSize = 64
func initOptions() {}
+7 -1
View File
@@ -22,7 +22,13 @@ import (
// fields can be get and set using the following methods:
// - Uint16/SetUint16: flags
// - Uint32/SetUint32: ifindex, metric, mtu
type Ifreq struct{ raw ifreq }
type Ifreq struct {
// Aligns the union for the accessors below, which cast it in place;
// the generated ifreq is all byte arrays, so its alignment is one.
_ [0]int64
raw ifreq
}
// NewIfreq creates an Ifreq with the input network interface name after
// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required)
+7
View File
@@ -332,3 +332,10 @@ func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
func IoctlLoopConfigure(fd int, value *LoopConfig) error {
return ioctlPtr(fd, LOOP_CONFIGURE, unsafe.Pointer(value))
}
// IoctlPidfdInfo fetches information about a pidfd.
// The Mask field of the info argument indicates which
// values to fetch.
func IoctlPidfdInfo(fd int, info *PidfdInfo) error {
return ioctlPtr(fd, PIDFD_GET_INFO, unsafe.Pointer(info))
}
+1 -8
View File
@@ -290,14 +290,7 @@ struct ltchars {
#include <mtd/mtd-user.h>
#include <net/route.h>
#if defined(__sparc__)
// On sparc{,64}, the kernel defines struct termios2 itself which clashes with the
// definition in glibc. As only the error constants are needed here, include the
// generic termibits.h (which is included by termbits.h on sparc).
#include <asm-generic/termbits.h>
#else
#include <asm/termbits.h>
#endif
#ifndef PTRACE_GETREGS
#define PTRACE_GETREGS 0xc
@@ -544,7 +537,7 @@ ccflags="$@"
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 == "LOOP_CONFIGURE" ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|MLOCK|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
$2 ~ /^PTP_/ ||
+1 -1
View File
@@ -76,7 +76,7 @@ func BytePtrToString(p *byte) string {
// Find NUL terminator.
n := 0
for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {
ptr = unsafe.Pointer(uintptr(ptr) + 1)
ptr = unsafe.Add(ptr, 1)
}
return string(unsafe.Slice(p, n))
+1 -1
View File
@@ -188,7 +188,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
}
sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
sa.raw.Family = AF_UNIX
for i := 0; i < n; i++ {
for i := range n {
sa.raw.Path[i] = int8(name[i])
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+1 -1
View File
@@ -2363,7 +2363,7 @@ func (fh *FileHandle) Bytes() []byte {
if n == 0 {
return nil
}
return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
return unsafe.Slice((*byte)(unsafe.Add(unsafe.Pointer(&fh.fileHandle.Type), 4)), n)
}
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
+2
View File
@@ -2048,6 +2048,7 @@ const (
MINIX3_SUPER_MAGIC = 0x4d5a
MINIX_SUPER_MAGIC = 0x137f
MINIX_SUPER_MAGIC2 = 0x138f
MLOCK_ONFAULT = 0x1
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
@@ -3862,6 +3863,7 @@ const (
TIOCPKT_NOSTOP = 0x10
TIOCPKT_START = 0x8
TIOCPKT_STOP = 0x4
TIOCSER_TEMT = 0x1
TIPC_ADDR_ID = 0x3
TIPC_ADDR_MCAST = 0x1
TIPC_ADDR_NAME = 0x2
-1
View File
@@ -483,7 +483,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
-1
View File
@@ -484,7 +484,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
-1
View File
@@ -489,7 +489,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
-1
View File
@@ -483,7 +483,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
-1
View File
@@ -476,7 +476,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
-1
View File
@@ -481,7 +481,6 @@ const (
TIOCSERGWILD = 0x5489
TIOCSERSETMULTI = 0x5490
TIOCSERSWILD = 0x548a
TIOCSER_TEMT = 0x1
TIOCSETD = 0x7401
TIOCSETN = 0x740a
TIOCSETP = 0x7409
-1
View File
@@ -481,7 +481,6 @@ const (
TIOCSERGWILD = 0x5489
TIOCSERSETMULTI = 0x5490
TIOCSERSWILD = 0x548a
TIOCSER_TEMT = 0x1
TIOCSETD = 0x7401
TIOCSETN = 0x740a
TIOCSETP = 0x7409
-1
View File
@@ -481,7 +481,6 @@ const (
TIOCSERGWILD = 0x5489
TIOCSERSETMULTI = 0x5490
TIOCSERSWILD = 0x548a
TIOCSER_TEMT = 0x1
TIOCSETD = 0x7401
TIOCSETN = 0x740a
TIOCSETP = 0x7409
-1
View File
@@ -481,7 +481,6 @@ const (
TIOCSERGWILD = 0x5489
TIOCSERSETMULTI = 0x5490
TIOCSERSWILD = 0x548a
TIOCSER_TEMT = 0x1
TIOCSETD = 0x7401
TIOCSETN = 0x740a
TIOCSETP = 0x7409
-1
View File
@@ -535,7 +535,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETC = 0x80067411
TIOCSETD = 0x5423
TIOCSETN = 0x8006740a
-1
View File
@@ -539,7 +539,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETC = 0x80067411
TIOCSETD = 0x5423
TIOCSETN = 0x8006740a
-1
View File
@@ -539,7 +539,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETC = 0x80067411
TIOCSETD = 0x5423
TIOCSETN = 0x8006740a
-1
View File
@@ -486,7 +486,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
-1
View File
@@ -545,7 +545,6 @@ const (
TIOCSERGWILD = 0x5454
TIOCSERSETMULTI = 0x545b
TIOCSERSWILD = 0x5455
TIOCSER_TEMT = 0x1
TIOCSETD = 0x5423
TIOCSIG = 0x40045436
TIOCSISO7816 = 0xc0285443
+20 -15
View File
@@ -14,21 +14,21 @@ const (
ASI_LEON_DFLUSH = 0x11
ASI_LEON_IFLUSH = 0x10
ASI_LEON_MMUFLUSH = 0x18
B1000000 = 0x1008
B1000000 = 0x100c
B115200 = 0x1002
B1152000 = 0x1009
B1500000 = 0x100a
B2000000 = 0x100b
B1152000 = 0x100d
B1500000 = 0x100e
B153600 = 0x1006
B2000000 = 0x100f
B230400 = 0x1003
B2500000 = 0x100c
B3000000 = 0x100d
B3500000 = 0x100e
B4000000 = 0x100f
B307200 = 0x1007
B460800 = 0x1004
B500000 = 0x1005
B500000 = 0x100a
B57600 = 0x1001
B576000 = 0x1006
B921600 = 0x1007
B576000 = 0x100b
B614400 = 0x1008
B76800 = 0x1005
B921600 = 0x1009
BLKALIGNOFF = 0x2000127a
BLKBSZGET = 0x40081270
BLKBSZSET = 0x80081271
@@ -91,7 +91,7 @@ const (
FFDLY = 0x8000
FICLONE = 0x80049409
FICLONERANGE = 0x8020940d
FLUSHO = 0x1000
FLUSHO = 0x2000
FS_IOC_ENABLE_VERITY = 0x80806685
FS_IOC_GETFLAGS = 0x40086601
FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b
@@ -563,6 +563,9 @@ const (
TIOCM_CD = 0x40
TIOCM_CTS = 0x20
TIOCM_DSR = 0x100
TIOCM_LOOP = 0x8000
TIOCM_OUT1 = 0x2000
TIOCM_OUT2 = 0x4000
TIOCM_RI = 0x80
TIOCM_RNG = 0x80
TIOCM_SR = 0x10
@@ -641,10 +644,11 @@ const (
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
VDISCARD = 0xd
VDSUSP = 0xb
VEOF = 0x4
VEOL = 0xb
VEOL2 = 0x10
VMIN = 0x6
VEOL = 0x5
VEOL2 = 0x6
VMIN = 0x4
VREPRINT = 0xc
VSTART = 0x8
VSTOP = 0x9
@@ -664,6 +668,7 @@ const (
WDIOC_KEEPALIVE = 0x40045705
WDIOC_SETOPTIONS = 0x40045704
WORDSIZE = 0x40
WRAP = 0x20000
XCASE = 0x4
XTABS = 0x1800
_HIDIOCGRAWNAME = 0x40804804
+79 -7
View File
@@ -4264,19 +4264,29 @@ type HwTstampConfig struct {
}
const (
HWTSTAMP_FILTER_NONE = 0x0
HWTSTAMP_FILTER_ALL = 0x1
HWTSTAMP_FILTER_SOME = 0x2
HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3
HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6
HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9
HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc
HWTSTAMP_FILTER_NONE = 0x0
HWTSTAMP_FILTER_ALL = 0x1
HWTSTAMP_FILTER_SOME = 0x2
HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3
HWTSTAMP_FILTER_PTP_V1_L4_SYNC = 0x4
HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ = 0x5
HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6
HWTSTAMP_FILTER_PTP_V2_L4_SYNC = 0x7
HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ = 0x8
HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9
HWTSTAMP_FILTER_PTP_V2_L2_SYNC = 0xa
HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ = 0xb
HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc
HWTSTAMP_FILTER_PTP_V2_SYNC = 0xd
HWTSTAMP_FILTER_PTP_V2_DELAY_REQ = 0xe
HWTSTAMP_FILTER_NTP_ALL = 0xf
)
const (
HWTSTAMP_TX_OFF = 0x0
HWTSTAMP_TX_ON = 0x1
HWTSTAMP_TX_ONESTEP_SYNC = 0x2
HWTSTAMP_TX_ONESTEP_P2P = 0x3
)
type (
@@ -4541,6 +4551,48 @@ const (
LANDLOCK_RULE_PATH_BENEATH = 0x1
)
const (
PIDFD_SIGNAL_THREAD = 0x1
PIDFD_SIGNAL_THREAD_GROUP = 0x2
PIDFD_SIGNAL_PROCESS_GROUP = 0x4
PIDFD_SELF_THREAD = -0x2710
PIDFD_SELF_THREAD_GROUP = -0x2711
PIDFD_SELF = -0x2710
PIDFD_SELF_PROCESS = -0x2711
PIDFD_INFO_PID = 0x1
PIDFD_INFO_CREDS = 0x2
PIDFD_INFO_CGROUPID = 0x4
PIDFD_INFO_EXIT = 0x8
PIDFD_INFO_COREDUMP = 0x10
PIDFD_COREDUMPED = 0x1
PIDFD_COREDUMP_SKIP = 0x2
PIDFD_COREDUMP_USER = 0x4
PIDFD_COREDUMP_ROOT = 0x8
PIDFD_INFO_SIZE_VER0 = 0x40
PIDFD_GET_INFO = 0xc048ff0b
)
const SizeofPidfdInfo = 0x48
type PidfdInfo struct {
Mask uint64
Cgroupid uint64
Pid uint32
Tgid uint32
Ppid uint32
Ruid uint32
Rgid uint32
Euid uint32
Egid uint32
Suid uint32
Sgid uint32
Fsuid uint32
Fsgid uint32
Exit_code int32
Coredump_mask uint32
_ uint32
}
const (
IPC_CREAT = 0x200
IPC_EXCL = 0x400
@@ -6473,3 +6525,23 @@ type GPIOV2LineEvent struct {
Line_seqno uint32
_ [6]uint32
}
const (
IPMI_MAX_ADDR_SIZE = 0x20
IPMI_SYSTEM_INTERFACE_ADDR_TYPE = 0xc
IPMI_BMC_CHANNEL = 0xf
IPMI_RESPONSE_RECV_TYPE = 0x1
)
type IPMISystemInterfaceAddr struct {
Type int32
Channel int16
Lun uint8
_ [1]byte
}
type IPMIMsg struct {
Netfn uint8
Cmd uint8
Len uint16
Data *uint8
}
+31 -1
View File
@@ -680,7 +680,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -715,3 +726,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8014690d
IPMICTL_RECEIVE_MSG = 0xc018690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int32
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int32
Msg IPMIMsg
}
+31 -1
View File
@@ -697,7 +697,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -729,3 +740,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -674,7 +674,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -709,3 +720,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8014690d
IPMICTL_RECEIVE_MSG = 0xc018690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int32
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int32
Msg IPMIMsg
}
+31 -1
View File
@@ -676,7 +676,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -708,3 +719,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -677,7 +677,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -709,3 +720,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -680,7 +680,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x80
PIDFD_NONBLOCK = 0x80
PIDFD_THREAD = 0x400
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -714,3 +725,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4014690d
IPMICTL_RECEIVE_MSG = 0xc018690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int32
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int32
Msg IPMIMsg
}
+31 -1
View File
@@ -679,7 +679,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x80
PIDFD_NONBLOCK = 0x80
PIDFD_THREAD = 0x400
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -711,3 +722,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -679,7 +679,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x80
PIDFD_NONBLOCK = 0x80
PIDFD_THREAD = 0x400
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -711,3 +722,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -680,7 +680,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x80
PIDFD_NONBLOCK = 0x80
PIDFD_THREAD = 0x400
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -714,3 +725,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4014690d
IPMICTL_RECEIVE_MSG = 0xc018690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int32
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int32
Msg IPMIMsg
}
+31 -1
View File
@@ -686,7 +686,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -722,3 +733,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4014690d
IPMICTL_RECEIVE_MSG = 0xc018690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int32
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int32
Msg IPMIMsg
}
+31 -1
View File
@@ -686,7 +686,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -717,3 +728,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -686,7 +686,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -717,3 +728,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -704,7 +704,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -796,3 +807,22 @@ const (
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -700,7 +700,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x800
PIDFD_NONBLOCK = 0x800
PIDFD_THREAD = 0x80
PIDFD_GET_CGROUP_NAMESPACE = 0xff01
PIDFD_GET_IPC_NAMESPACE = 0xff02
PIDFD_GET_MNT_NAMESPACE = 0xff03
PIDFD_GET_NET_NAMESPACE = 0xff04
PIDFD_GET_PID_NAMESPACE = 0xff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06
PIDFD_GET_TIME_NAMESPACE = 0xff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08
PIDFD_GET_USER_NAMESPACE = 0xff09
PIDFD_GET_UTS_NAMESPACE = 0xff0a
)
type SysvIpcPerm struct {
@@ -731,3 +742,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
)
const (
IPMICTL_SEND_COMMAND = 0x8028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+31 -1
View File
@@ -681,7 +681,18 @@ const (
)
const (
PIDFD_NONBLOCK = 0x4000
PIDFD_NONBLOCK = 0x4000
PIDFD_THREAD = 0x800
PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01
PIDFD_GET_IPC_NAMESPACE = 0x2000ff02
PIDFD_GET_MNT_NAMESPACE = 0x2000ff03
PIDFD_GET_NET_NAMESPACE = 0x2000ff04
PIDFD_GET_PID_NAMESPACE = 0x2000ff05
PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06
PIDFD_GET_TIME_NAMESPACE = 0x2000ff07
PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08
PIDFD_GET_USER_NAMESPACE = 0x2000ff09
PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a
)
type SysvIpcPerm struct {
@@ -712,3 +723,22 @@ type SysvShmDesc struct {
const (
GPIO_GET_CHIPINFO_IOCTL = 0x4044b401
)
const (
IPMICTL_SEND_COMMAND = 0x4028690d
IPMICTL_RECEIVE_MSG = 0xc030690c
)
type IPMIReq struct {
Addr *uint8
Len uint32
Msgid int64
Msg IPMIMsg
}
type IPMIRecv struct {
Recv_type int32
Addr *uint8
Addr_len uint32
Msgid int64
Msg IPMIMsg
}
+1
View File
@@ -1065,6 +1065,7 @@ const (
SO_BROADCAST = 32
SO_LINGER = 128
SO_RCVBUF = 0x1002
SO_SNDTIMEO = 0x1005
SO_RCVTIMEO = 0x1006
SO_SNDBUF = 0x1001
SO_UPDATE_ACCEPT_CONTEXT = 0x700b
+17 -7
View File
@@ -106,6 +106,9 @@ type Terminal struct {
// a read. It aliases into inBuf.
remainder []byte
inBuf [256]byte
// readErr is an error returned by a read that also returned data. It is
// reported after all of that data has been processed.
readErr error
// History records and retrieves lines of input read by [ReadLine] which
// a user can retrieve and navigate using the up and down arrow keys.
@@ -788,7 +791,11 @@ func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
return
}
// ReadLine returns a line of input from the terminal.
// ReadLine returns a line of input from the terminal, excluding the
// trailing newline. It may return partial data along with an error.
// An [io.EOF] error indicates the end of the stream. For other errors,
// such as [ErrPasteIndicator] in bracketed paste mode, a subsequent
// call may return more data.
func (t *Terminal) ReadLine() (line string, err error) {
t.lock.Lock()
defer t.lock.Unlock()
@@ -863,21 +870,24 @@ func (t *Terminal) readLine() (line string, err error) {
}
return
}
if t.readErr != nil {
err = t.readErr
t.readErr = nil
return
}
// t.remainder is a slice at the beginning of t.inBuf
// containing a partial key sequence
readBuf := t.inBuf[len(t.remainder):]
var n int
t.lock.Unlock()
n, err = t.c.Read(readBuf)
n, readErr := t.c.Read(readBuf)
t.lock.Lock()
if err != nil {
return
}
t.remainder = t.inBuf[:n+len(t.remainder)]
if readErr != nil {
t.readErr = readErr
}
}
}
Generated Vendored
+4 -4
View File
@@ -743,16 +743,16 @@ golang.org/x/net/internal/socks
golang.org/x/net/internal/timeseries
golang.org/x/net/proxy
golang.org/x/net/trace
# golang.org/x/sys v0.47.0
## explicit; go 1.25.0
# golang.org/x/sys v0.48.0
## explicit; go 1.26.0
golang.org/x/sys/cpu
golang.org/x/sys/execabs
golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
golang.org/x/sys/windows/registry
# golang.org/x/term v0.45.0
## explicit; go 1.25.0
# golang.org/x/term v0.46.0
## explicit; go 1.26.0
golang.org/x/term
# golang.org/x/text v0.39.0
## explicit; go 1.25.0