Compare commits
45 Commits
Author | SHA1 | Date |
---|---|---|
CrazyMax | 4e547752af | 1 year ago |
CrazyMax | 95eee3e747 | 1 year ago |
CrazyMax | d5bfd8334f | 2 years ago |
CrazyMax | 2083f24938 | 2 years ago |
CrazyMax | 84da4ec603 | 2 years ago |
Sebastiaan van Stijn | 35dac12ae5 | 2 years ago |
Sebastiaan van Stijn | 27f332f135 | 2 years ago |
Justin Chadwell | 9872040b66 | 2 years ago |
Sebastiaan van Stijn | d8c6c3fc30 | 2 years ago |
Sebastiaan van Stijn | 69f929077b | 2 years ago |
Sebastiaan van Stijn | 87ce701fe0 | 2 years ago |
Justin Chadwell | 6faf7e5688 | 2 years ago |
Justin Chadwell | d21e9fa8c6 | 2 years ago |
Justin Chadwell | 5657006c1f | 2 years ago |
Justin Chadwell | 0424ae14c0 | 2 years ago |
Justin Chadwell | 66fd2bbdee | 2 years ago |
CrazyMax | 3305f18ce5 | 2 years ago |
CrazyMax | a8790788d1 | 2 years ago |
CrazyMax | 0f6513a29a | 2 years ago |
Justin Chadwell | 44f5946a66 | 2 years ago |
CrazyMax | ea610d8f14 | 2 years ago |
Sebastiaan van Stijn | d78c75947d | 2 years ago |
CrazyMax | 7dddd3a7d3 | 2 years ago |
CrazyMax | 54de900931 | 2 years ago |
Justin Chadwell | 50e414f82a | 2 years ago |
Justin Chadwell | a24b6dd4f5 | 2 years ago |
CrazyMax | 66600be6ab | 2 years ago |
Justin Chadwell | b4df08551f | 2 years ago |
Justin Chadwell | f581942d7d | 2 years ago |
Justin Chadwell | 5159571dfc | 2 years ago |
Justin Chadwell | 86a5c77c2b | 2 years ago |
Justin Chadwell | 1602b491f9 | 2 years ago |
CrazyMax | 94baaf3c90 | 2 years ago |
CrazyMax | c5e279f295 | 2 years ago |
CrazyMax | a0f91eb87e | 2 years ago |
CrazyMax | cb1812ec6a | 2 years ago |
CrazyMax | 47e4c2576b | 2 years ago |
CrazyMax | 3702e17ed5 | 2 years ago |
Jhan S. Álvarez | 8b85dbea72 | 2 years ago |
CrazyMax | afcb118e10 | 2 years ago |
David Karlsson | cb4fea66e0 | 2 years ago |
CrazyMax | 74fa66b496 | 2 years ago |
Justin Chadwell | ff87dd183a | 2 years ago |
CrazyMax | 9f844df9f7 | 2 years ago |
Justin Chadwell | bc597e6b5e | 2 years ago |
@ -1,25 +0,0 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/go
|
||||
{
|
||||
"name": "Go",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/go:1-1.21-bullseye",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
||||
}
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "go version",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
Binary file not shown.
@ -1,267 +0,0 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var imagetoolsTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testImagetoolsCopyManifest,
|
||||
testImagetoolsCopyIndex,
|
||||
testImagetoolsInspectAndFilter,
|
||||
testImagetoolsAnnotation,
|
||||
}
|
||||
|
||||
func testImagetoolsCopyManifest(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools-manifest:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var mfst ocispecs.Manifest
|
||||
err = json.Unmarshal(dt, &mfst)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2Manifest, mfst.MediaType)
|
||||
|
||||
registry2, err := sb.NewRegistry()
|
||||
require.NoError(t, err)
|
||||
target2 := registry2 + "/buildx/imtools2-manifest:latest"
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target2, target))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2, "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx2 ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx2.MediaType)
|
||||
require.Equal(t, 1, len(idx2.Manifests))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2+"@"+string(idx2.Manifests[0].Digest), "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var mfst2 ocispecs.Manifest
|
||||
err = json.Unmarshal(dt, &mfst2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2Manifest, mfst2.MediaType)
|
||||
|
||||
require.Equal(t, mfst.Config.Digest, mfst2.Config.Digest)
|
||||
require.Equal(t, len(mfst.Layers), len(mfst2.Layers))
|
||||
for i := range mfst.Layers {
|
||||
require.Equal(t, mfst.Layers[i].Digest, mfst2.Layers[i].Digest)
|
||||
}
|
||||
}
|
||||
|
||||
func testImagetoolsCopyIndex(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx.MediaType)
|
||||
require.Equal(t, 2, len(idx.Manifests))
|
||||
|
||||
registry2, err := sb.NewRegistry()
|
||||
require.NoError(t, err)
|
||||
target2 := registry2 + "/buildx/imtools2:latest"
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target2, target))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2, "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx2 ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx2.MediaType)
|
||||
|
||||
require.Equal(t, len(idx.Manifests), len(idx2.Manifests))
|
||||
for i := range idx.Manifests {
|
||||
require.Equal(t, idx.Manifests[i].Digest, idx2.Manifests[i].Digest)
|
||||
}
|
||||
}
|
||||
|
||||
func testImagetoolsInspectAndFilter(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 2, len(idx.Manifests))
|
||||
|
||||
mfst := idx.Manifests[0]
|
||||
require.Equal(t, "linux/amd64", platforms.Format(*mfst.Platform))
|
||||
|
||||
mfst = idx.Manifests[1]
|
||||
require.Equal(t, "linux/arm64", platforms.Format(*mfst.Platform))
|
||||
|
||||
// create amd64 only image
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target+"-arm64", target+"@"+string(idx.Manifests[1].Digest)))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target+"-arm64", "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx2 ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx2)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(idx2.Manifests))
|
||||
|
||||
require.Equal(t, idx.Manifests[1].Digest, idx2.Manifests[0].Digest)
|
||||
require.Equal(t, platforms.Format(*idx.Manifests[1].Platform), platforms.Format(*idx2.Manifests[0].Platform))
|
||||
}
|
||||
|
||||
func testImagetoolsAnnotation(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("--output", "type=registry,oci-mediatypes=true,name="+target, "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, idx.Annotations)
|
||||
|
||||
imagetoolsCmd := func(source []string) *exec.Cmd {
|
||||
args := []string{"imagetools", "create", "-t", target, "--annotation", "index:foo=bar", "--annotation", "index:bar=baz",
|
||||
"--annotation", "manifest-descriptor:foo=bar", "--annotation", "manifest-descriptor[linux/amd64]:bar=baz"}
|
||||
args = append(args, source...)
|
||||
return buildxCmd(sb, withArgs(args...))
|
||||
}
|
||||
sources := [][]string{
|
||||
{
|
||||
target,
|
||||
},
|
||||
{
|
||||
target + "@" + string(idx.Manifests[0].Digest),
|
||||
target + "@" + string(idx.Manifests[1].Digest),
|
||||
},
|
||||
}
|
||||
for _, source := range sources {
|
||||
cmd = imagetoolsCmd(source)
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
newTarget := registry + "/buildx/imtools:annotations"
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", newTarget, target))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", newTarget, "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, idx.Annotations, 2)
|
||||
require.Equal(t, "bar", idx.Annotations["foo"])
|
||||
require.Equal(t, "baz", idx.Annotations["bar"])
|
||||
require.Len(t, idx.Manifests, 2)
|
||||
for _, mfst := range idx.Manifests {
|
||||
require.Equal(t, "bar", mfst.Annotations["foo"])
|
||||
if platforms.Format(*mfst.Platform) == "linux/amd64" {
|
||||
require.Equal(t, "baz", mfst.Annotations["bar"])
|
||||
} else {
|
||||
require.Empty(t, mfst.Annotations["bar"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createDockerfile(t *testing.T) string {
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
ARG TARGETARCH
|
||||
COPY foo-${TARGETARCH} /foo
|
||||
`)
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("foo-amd64", []byte("foo-amd64"), 0600),
|
||||
fstest.CreateFile("foo-arm64", []byte("foo-arm64"), 0600),
|
||||
)
|
||||
return dir
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var versionTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testVersion,
|
||||
}
|
||||
|
||||
func testVersion(t *testing.T, sb integration.Sandbox) {
|
||||
cmd := buildxCmd(sb, withArgs("version"))
|
||||
out, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
// There should be at least one newline and the first line
|
||||
// of output should contain the name, version, and possibly a revision.
|
||||
firstLine, _, hasNewline := strings.Cut(string(out), "\n")
|
||||
require.True(t, hasNewline, "At least one newline is required in the output")
|
||||
|
||||
// Log the output to make debugging easier.
|
||||
t.Log(firstLine)
|
||||
|
||||
// Split by spaces into at least 2 fields.
|
||||
fields := strings.Fields(firstLine)
|
||||
require.GreaterOrEqual(t, len(fields), 2, "Expected at least 2 fields in the first line")
|
||||
|
||||
// First field should be an import path.
|
||||
// This can be any valid import path for Go
|
||||
// so don't set too many restrictions here.
|
||||
// Just checking if the import path is a valid Go
|
||||
// path should be suitable enough to make sure this is ok.
|
||||
// Using CheckImportPath instead of CheckPath as it is less
|
||||
// restrictive.
|
||||
importPath := fields[0]
|
||||
require.NoError(t, module.CheckImportPath(importPath), "First field was not a valid import path: %+v", importPath)
|
||||
|
||||
// Second field should be a version.
|
||||
// This defaults to something that's still compatible
|
||||
// with semver.
|
||||
version := fields[1]
|
||||
require.True(t, semver.IsValid(version), "Second field was not valid semver: %+v", version)
|
||||
|
||||
// Revision should be empty or should look like a git hash.
|
||||
if len(fields) > 2 && len(fields[2]) > 0 {
|
||||
revision := fields[2]
|
||||
require.Regexp(t, `[0-9a-f]{40}`, revision, "Third field was not a git revision: %+v", revision)
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
)
|
||||
|
||||
var features = map[string]struct{}{}
|
||||
|
||||
func CheckFeatureCompat(t *testing.T, sb integration.Sandbox, reason ...string) {
|
||||
integration.CheckFeatureCompat(t, sb, features, reason...)
|
||||
}
|
@ -1,15 +1,21 @@
|
||||
package buildflags
|
||||
|
||||
import "github.com/moby/buildkit/util/entitlements"
|
||||
import (
|
||||
"github.com/moby/buildkit/util/entitlements"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func ParseEntitlements(in []string) ([]entitlements.Entitlement, error) {
|
||||
out := make([]entitlements.Entitlement, 0, len(in))
|
||||
for _, v := range in {
|
||||
e, err := entitlements.Parse(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
switch v {
|
||||
case "security.insecure":
|
||||
out = append(out, entitlements.EntitlementSecurityInsecure)
|
||||
case "network.host":
|
||||
out = append(out, entitlements.EntitlementNetworkHost)
|
||||
default:
|
||||
return nil, errors.Errorf("invalid entitlement: %v", v)
|
||||
}
|
||||
out = append(out, e)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Compose Specification Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package dotenv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func GetEnvFromFile(currentEnv map[string]string, workingDir string, filenames []string) (map[string]string, error) {
|
||||
envMap := make(map[string]string)
|
||||
|
||||
dotEnvFiles := filenames
|
||||
if len(dotEnvFiles) == 0 {
|
||||
dotEnvFiles = append(dotEnvFiles, filepath.Join(workingDir, ".env"))
|
||||
}
|
||||
for _, dotEnvFile := range dotEnvFiles {
|
||||
abs, err := filepath.Abs(dotEnvFile)
|
||||
if err != nil {
|
||||
return envMap, err
|
||||
}
|
||||
dotEnvFile = abs
|
||||
|
||||
s, err := os.Stat(dotEnvFile)
|
||||
if os.IsNotExist(err) {
|
||||
if len(filenames) == 0 {
|
||||
return envMap, nil
|
||||
}
|
||||
return envMap, errors.Errorf("Couldn't find env file: %s", dotEnvFile)
|
||||
}
|
||||
if err != nil {
|
||||
return envMap, err
|
||||
}
|
||||
|
||||
if s.IsDir() {
|
||||
if len(filenames) == 0 {
|
||||
return envMap, nil
|
||||
}
|
||||
return envMap, errors.Errorf("%s is a directory", dotEnvFile)
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(dotEnvFile)
|
||||
if os.IsNotExist(err) {
|
||||
return nil, errors.Errorf("Couldn't read env file: %s", dotEnvFile)
|
||||
}
|
||||
if err != nil {
|
||||
return envMap, err
|
||||
}
|
||||
|
||||
env, err := ParseWithLookup(bytes.NewReader(b), func(k string) (string, bool) {
|
||||
v, ok := currentEnv[k]
|
||||
if ok {
|
||||
return v, true
|
||||
}
|
||||
v, ok = envMap[k]
|
||||
return v, ok
|
||||
})
|
||||
if err != nil {
|
||||
return envMap, errors.Wrapf(err, "failed to read %s", dotEnvFile)
|
||||
}
|
||||
for k, v := range env {
|
||||
envMap[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return envMap, nil
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Compose Specification Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/compose-spec/compose-go/dotenv"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// LoadIncludeConfig parse the require config from raw yaml
|
||||
func LoadIncludeConfig(source []interface{}) ([]types.IncludeConfig, error) {
|
||||
var requires []types.IncludeConfig
|
||||
err := Transform(source, &requires)
|
||||
return requires, err
|
||||
}
|
||||
|
||||
var transformIncludeConfig TransformerFunc = func(data interface{}) (interface{}, error) {
|
||||
switch value := data.(type) {
|
||||
case string:
|
||||
return map[string]interface{}{"path": value}, nil
|
||||
case map[string]interface{}:
|
||||
return value, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for `include` configuration", value)
|
||||
}
|
||||
}
|
||||
|
||||
func loadInclude(configDetails types.ConfigDetails, model *types.Config, options *Options, loaded []string) (*types.Config, error) {
|
||||
for _, r := range model.Include {
|
||||
for i, p := range r.Path {
|
||||
if !filepath.IsAbs(p) {
|
||||
r.Path[i] = filepath.Join(configDetails.WorkingDir, p)
|
||||
}
|
||||
}
|
||||
if r.ProjectDirectory == "" {
|
||||
r.ProjectDirectory = filepath.Dir(r.Path[0])
|
||||
}
|
||||
|
||||
loadOptions := options.clone()
|
||||
loadOptions.SetProjectName(model.Name, true)
|
||||
loadOptions.ResolvePaths = true
|
||||
loadOptions.SkipNormalization = true
|
||||
loadOptions.SkipConsistencyCheck = true
|
||||
|
||||
env, err := dotenv.GetEnvFromFile(configDetails.Environment, r.ProjectDirectory, r.EnvFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imported, err := load(types.ConfigDetails{
|
||||
WorkingDir: r.ProjectDirectory,
|
||||
ConfigFiles: types.ToConfigFiles(r.Path),
|
||||
Environment: env,
|
||||
}, loadOptions, loaded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = importResources(model, imported, r.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
model.Include = nil
|
||||
return model, nil
|
||||
}
|
||||
|
||||
// importResources import into model all resources defined by imported, and report error on conflict
|
||||
func importResources(model *types.Config, imported *types.Project, path []string) error {
|
||||
services := mapByName(model.Services)
|
||||
for _, service := range imported.Services {
|
||||
if _, ok := services[service.Name]; ok {
|
||||
return fmt.Errorf("imported compose file %s defines conflicting service %s", path, service.Name)
|
||||
}
|
||||
model.Services = append(model.Services, service)
|
||||
}
|
||||
for n, network := range imported.Networks {
|
||||
if _, ok := model.Networks[n]; ok {
|
||||
return fmt.Errorf("imported compose file %s defines conflicting network %s", path, n)
|
||||
}
|
||||
model.Networks[n] = network
|
||||
}
|
||||
for n, volume := range imported.Volumes {
|
||||
if _, ok := model.Volumes[n]; ok {
|
||||
return fmt.Errorf("imported compose file %s defines conflicting volume %s", path, n)
|
||||
}
|
||||
model.Volumes[n] = volume
|
||||
}
|
||||
for n, secret := range imported.Secrets {
|
||||
if _, ok := model.Secrets[n]; ok {
|
||||
return fmt.Errorf("imported compose file %s defines conflicting secret %s", path, n)
|
||||
}
|
||||
model.Secrets[n] = secret
|
||||
}
|
||||
for n, config := range imported.Configs {
|
||||
if _, ok := model.Configs[n]; ok {
|
||||
return fmt.Errorf("imported compose file %s defines conflicting config %s", path, n)
|
||||
}
|
||||
model.Configs[n] = config
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Compose Specification Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
)
|
||||
|
||||
// ResolveRelativePaths resolves relative paths based on project WorkingDirectory
|
||||
func ResolveRelativePaths(project *types.Project) error {
|
||||
absWorkingDir, err := filepath.Abs(project.WorkingDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
project.WorkingDir = absWorkingDir
|
||||
|
||||
absComposeFiles, err := absComposeFiles(project.ComposeFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
project.ComposeFiles = absComposeFiles
|
||||
|
||||
for i, s := range project.Services {
|
||||
ResolveServiceRelativePaths(project.WorkingDir, &s)
|
||||
project.Services[i] = s
|
||||
}
|
||||
|
||||
for i, obj := range project.Configs {
|
||||
if obj.File != "" {
|
||||
obj.File = absPath(project.WorkingDir, obj.File)
|
||||
project.Configs[i] = obj
|
||||
}
|
||||
}
|
||||
|
||||
for i, obj := range project.Secrets {
|
||||
if obj.File != "" {
|
||||
obj.File = resolveMaybeUnixPath(project.WorkingDir, obj.File)
|
||||
project.Secrets[i] = obj
|
||||
}
|
||||
}
|
||||
|
||||
for name, config := range project.Volumes {
|
||||
if config.Driver == "local" && config.DriverOpts["o"] == "bind" {
|
||||
// This is actually a bind mount
|
||||
config.DriverOpts["device"] = resolveMaybeUnixPath(project.WorkingDir, config.DriverOpts["device"])
|
||||
project.Volumes[name] = config
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResolveServiceRelativePaths(workingDir string, s *types.ServiceConfig) {
|
||||
if s.Build != nil {
|
||||
if !isRemoteContext(s.Build.Context) {
|
||||
s.Build.Context = absPath(workingDir, s.Build.Context)
|
||||
}
|
||||
for name, path := range s.Build.AdditionalContexts {
|
||||
if strings.Contains(path, "://") { // `docker-image://` or any builder specific context type
|
||||
continue
|
||||
}
|
||||
if isRemoteContext(path) {
|
||||
continue
|
||||
}
|
||||
s.Build.AdditionalContexts[name] = absPath(workingDir, path)
|
||||
}
|
||||
}
|
||||
for j, f := range s.EnvFile {
|
||||
s.EnvFile[j] = absPath(workingDir, f)
|
||||
}
|
||||
|
||||
if s.Extends != nil && s.Extends.File != "" {
|
||||
s.Extends.File = absPath(workingDir, s.Extends.File)
|
||||
}
|
||||
|
||||
for i, vol := range s.Volumes {
|
||||
if vol.Type != types.VolumeTypeBind {
|
||||
continue
|
||||
}
|
||||
s.Volumes[i].Source = resolveMaybeUnixPath(workingDir, vol.Source)
|
||||
}
|
||||
}
|
||||
|
||||
func absPath(workingDir string, filePath string) string {
|
||||
if strings.HasPrefix(filePath, "~") {
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, filePath[1:])
|
||||
}
|
||||
if filepath.IsAbs(filePath) {
|
||||
return filePath
|
||||
}
|
||||
return filepath.Join(workingDir, filePath)
|
||||
}
|
||||
|
||||
func absComposeFiles(composeFiles []string) ([]string, error) {
|
||||
for i, composeFile := range composeFiles {
|
||||
absComposefile, err := filepath.Abs(composeFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
composeFiles[i] = absComposefile
|
||||
}
|
||||
return composeFiles, nil
|
||||
}
|
||||
|
||||
// isRemoteContext returns true if the value is a Git reference or HTTP(S) URL.
|
||||
//
|
||||
// Any other value is assumed to be a local filesystem path and returns false.
|
||||
//
|
||||
// See: https://github.com/moby/buildkit/blob/18fc875d9bfd6e065cd8211abc639434ba65aa56/frontend/dockerui/context.go#L76-L79
|
||||
func isRemoteContext(maybeURL string) bool {
|
||||
for _, prefix := range []string{"https://", "http://", "git://", "ssh://", "github.com/", "git@"} {
|
||||
if strings.HasPrefix(maybeURL, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Compose Specification Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import "golang.org/x/exp/slices"
|
||||
|
||||
func MapKeys[T comparable, U any](theMap map[T]U) []T {
|
||||
var result []T
|
||||
for key := range theMap {
|
||||
result = append(result, key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func MapsAppend[T comparable, U any](target map[T]U, source map[T]U) map[T]U {
|
||||
if target == nil {
|
||||
return source
|
||||
}
|
||||
if source == nil {
|
||||
return target
|
||||
}
|
||||
for key, value := range source {
|
||||
if _, ok := target[key]; !ok {
|
||||
target[key] = value
|
||||
}
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
func ArrayContains[T comparable](source []T, toCheck []T) bool {
|
||||
for _, value := range toCheck {
|
||||
if !slices.Contains(source, value) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
[568].out
|
||||
_go*
|
||||
_test*
|
||||
_obj
|
@ -1,17 +0,0 @@
|
||||
ARG GOVERSION=1.14
|
||||
FROM golang:${GOVERSION}
|
||||
|
||||
# Set base env.
|
||||
ARG GOOS=linux
|
||||
ARG GOARCH=amd64
|
||||
ENV GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w'
|
||||
|
||||
# Pre compile the stdlib for 386/arm (32bits).
|
||||
RUN go build -a std
|
||||
|
||||
# Add the code to the image.
|
||||
WORKDIR pty
|
||||
ADD . .
|
||||
|
||||
# Build the lib.
|
||||
RUN go build
|
@ -1,23 +0,0 @@
|
||||
# NOTE: Using 1.13 as a base to build the RISCV compiler, the resulting version is based on go1.6.
|
||||
FROM golang:1.13
|
||||
|
||||
# Clone and complie a riscv compatible version of the go compiler.
|
||||
RUN git clone https://review.gerrithub.io/riscv/riscv-go /riscv-go
|
||||
# riscvdev branch HEAD as of 2019-06-29.
|
||||
RUN cd /riscv-go && git checkout 04885fddd096d09d4450726064d06dd107e374bf
|
||||
ENV PATH=/riscv-go/misc/riscv:/riscv-go/bin:$PATH
|
||||
RUN cd /riscv-go/src && GOROOT_BOOTSTRAP=$(go env GOROOT) ./make.bash
|
||||
ENV GOROOT=/riscv-go
|
||||
|
||||
# Set the base env.
|
||||
ENV GOOS=linux GOARCH=riscv CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w'
|
||||
|
||||
# Pre compile the stdlib.
|
||||
RUN go build -a std
|
||||
|
||||
# Add the code to the image.
|
||||
WORKDIR pty
|
||||
ADD . .
|
||||
|
||||
# Build the lib.
|
||||
RUN go build
|
@ -1,23 +0,0 @@
|
||||
Copyright (c) 2011 Keith Rarick
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall
|
||||
be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,107 +0,0 @@
|
||||
# pty
|
||||
|
||||
Pty is a Go package for using unix pseudo-terminals.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
go get github.com/creack/pty
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment.
|
||||
|
||||
### Command
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/creack/pty"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := exec.Command("grep", "--color=auto", "bar")
|
||||
f, err := pty.Start(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
f.Write([]byte("foo\n"))
|
||||
f.Write([]byte("bar\n"))
|
||||
f.Write([]byte("baz\n"))
|
||||
f.Write([]byte{4}) // EOT
|
||||
}()
|
||||
io.Copy(os.Stdout, f)
|
||||
}
|
||||
```
|
||||
|
||||
### Shell
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/creack/pty"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
func test() error {
|
||||
// Create arbitrary command.
|
||||
c := exec.Command("bash")
|
||||
|
||||
// Start the command with a pty.
|
||||
ptmx, err := pty.Start(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure to close the pty at the end.
|
||||
defer func() { _ = ptmx.Close() }() // Best effort.
|
||||
|
||||
// Handle pty size.
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGWINCH)
|
||||
go func() {
|
||||
for range ch {
|
||||
if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
|
||||
log.Printf("error resizing pty: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
ch <- syscall.SIGWINCH // Initial resize.
|
||||
defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done.
|
||||
|
||||
// Set stdin in raw mode.
|
||||
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
|
||||
|
||||
// Copy stdin to the pty and the pty to stdout.
|
||||
// NOTE: The goroutine will keep reading until the next keystroke before returning.
|
||||
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
|
||||
_, _ = io.Copy(os.Stdout, ptmx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := test(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
// Copyright 2014 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
|
||||
//+build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
||||
//
|
||||
|
||||
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·sysvicall6(SB)
|
||||
|
||||
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·rawSysvicall6(SB)
|
@ -1,16 +0,0 @@
|
||||
// Package pty provides functions for working with Unix terminals.
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ErrUnsupported is returned if a function is not
|
||||
// available on the current platform.
|
||||
var ErrUnsupported = errors.New("unsupported")
|
||||
|
||||
// Open a pty and its corresponding tty.
|
||||
func Open() (pty, tty *os.File, err error) {
|
||||
return open()
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
//go:build !windows && !solaris && !aix
|
||||
// +build !windows,!solaris,!aix
|
||||
|
||||
package pty
|
||||
|
||||
import "syscall"
|
||||
|
||||
const (
|
||||
TIOCGWINSZ = syscall.TIOCGWINSZ
|
||||
TIOCSWINSZ = syscall.TIOCSWINSZ
|
||||
)
|
||||
|
||||
func ioctl(fd, cmd, ptr uintptr) error {
|
||||
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
|
||||
if e != 0 {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package pty
|
||||
|
||||
// from <sys/ioccom.h>
|
||||
const (
|
||||
_IOC_VOID uintptr = 0x20000000
|
||||
_IOC_OUT uintptr = 0x40000000
|
||||
_IOC_IN uintptr = 0x80000000
|
||||
_IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN
|
||||
_IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN
|
||||
|
||||
_IOC_PARAM_SHIFT = 13
|
||||
_IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
|
||||
)
|
||||
|
||||
func _IOC_PARM_LEN(ioctl uintptr) uintptr {
|
||||
return (ioctl >> 16) & _IOC_PARAM_MASK
|
||||
}
|
||||
|
||||
func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num
|
||||
}
|
||||
|
||||
func _IO(group byte, ioctl_num uintptr) uintptr {
|
||||
return _IOC(_IOC_VOID, group, ioctl_num, 0)
|
||||
}
|
||||
|
||||
func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return _IOC(_IOC_OUT, group, ioctl_num, param_len)
|
||||
}
|
||||
|
||||
func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return _IOC(_IOC_IN, group, ioctl_num, param_len)
|
||||
}
|
||||
|
||||
func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len)
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
//go:build solaris
|
||||
// +build solaris
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
|
||||
//go:linkname procioctl libc_ioctl
|
||||
var procioctl uintptr
|
||||
|
||||
const (
|
||||
// see /usr/include/sys/stropts.h
|
||||
I_PUSH = uintptr((int32('S')<<8 | 002))
|
||||
I_STR = uintptr((int32('S')<<8 | 010))
|
||||
I_FIND = uintptr((int32('S')<<8 | 013))
|
||||
|
||||
// see /usr/include/sys/ptms.h
|
||||
ISPTM = (int32('P') << 8) | 1
|
||||
UNLKPT = (int32('P') << 8) | 2
|
||||
PTSSTTY = (int32('P') << 8) | 3
|
||||
ZONEPT = (int32('P') << 8) | 4
|
||||
OWNERPT = (int32('P') << 8) | 5
|
||||
|
||||
// see /usr/include/sys/termios.h
|
||||
TIOCSWINSZ = (uint32('T') << 8) | 103
|
||||
TIOCGWINSZ = (uint32('T') << 8) | 104
|
||||
)
|
||||
|
||||
type strioctl struct {
|
||||
icCmd int32
|
||||
icTimeout int32
|
||||
icLen int32
|
||||
icDP unsafe.Pointer
|
||||
}
|
||||
|
||||
// Defined in asm_solaris_amd64.s.
|
||||
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func ioctl(fd, cmd, ptr uintptr) error {
|
||||
if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
//go:build aix
|
||||
// +build aix
|
||||
|
||||
package pty
|
||||
|
||||
const (
|
||||
TIOCGWINSZ = 0
|
||||
TIOCSWINSZ = 0
|
||||
)
|
||||
|
||||
func ioctl(fd, cmd, ptr uintptr) error {
|
||||
return ErrUnsupported
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
GOOSARCH="${GOOS}_${GOARCH}"
|
||||
case "$GOOSARCH" in
|
||||
_* | *_ | _)
|
||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
GODEFS="go tool cgo -godefs"
|
||||
|
||||
$GODEFS types.go |gofmt > ztypes_$GOARCH.go
|
||||
|
||||
case $GOOS in
|
||||
freebsd|dragonfly|netbsd|openbsd)
|
||||
$GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go
|
||||
;;
|
||||
esac
|
@ -1,68 +0,0 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
p := os.NewFile(uintptr(pFD), "/dev/ptmx")
|
||||
// In case of error after this point, make sure we close the ptmx fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := grantpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := unlockpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
|
||||
|
||||
err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range n {
|
||||
if c == 0 {
|
||||
return string(n[:i]), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
||||
}
|
||||
|
||||
func grantpt(f *os.File) error {
|
||||
return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0)
|
||||
}
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0)
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
//go:build dragonfly
|
||||
// +build dragonfly
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// same code as pty_darwin.go
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// In case of error after this point, make sure we close the ptmx fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := grantpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := unlockpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile(sname, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func grantpt(f *os.File) error {
|
||||
_, err := isptmaster(f.Fd())
|
||||
return err
|
||||
}
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
_, err := isptmaster(f.Fd())
|
||||
return err
|
||||
}
|
||||
|
||||
func isptmaster(fd uintptr) (bool, error) {
|
||||
err := ioctl(fd, syscall.TIOCISPTMASTER, 0)
|
||||
return err == nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
emptyFiodgnameArg fiodgnameArg
|
||||
ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
|
||||
)
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
name := make([]byte, _C_SPECNAMELEN)
|
||||
fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}}
|
||||
|
||||
err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range name {
|
||||
if c == 0 {
|
||||
s := "/dev/" + string(name[:i])
|
||||
return strings.Replace(s, "ptm", "pts", -1), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
//go:build freebsd
|
||||
// +build freebsd
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func posixOpenpt(oflag int) (fd int, err error) {
|
||||
r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0)
|
||||
fd = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return fd, err
|
||||
}
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
p := os.NewFile(uintptr(fd), "/dev/pts")
|
||||
// In case of error after this point, make sure we close the pts fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func isptmaster(fd uintptr) (bool, error) {
|
||||
err := ioctl(fd, syscall.TIOCPTMASTER, 0)
|
||||
return err == nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
emptyFiodgnameArg fiodgnameArg
|
||||
ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
|
||||
)
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
master, err := isptmaster(f.Fd())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !master {
|
||||
return "", syscall.EINVAL
|
||||
}
|
||||
|
||||
const n = _C_SPECNAMELEN + 1
|
||||
var (
|
||||
buf = make([]byte, n)
|
||||
arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))}
|
||||
)
|
||||
if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range buf {
|
||||
if c == 0 {
|
||||
return string(buf[:i]), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("FIODGNAME string not NUL-terminated")
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue