Răsfoiți Sursa

use new moby/moby modules instead of docker/docker dependency

Signed-off-by: Guillaume Lours <[email protected]>
Guillaume Lours 2 săptămâni în urmă
părinte
comite
ba417e4392

+ 1 - 1
go.mod

@@ -18,7 +18,6 @@ require (
 	github.com/docker/buildx v0.33.0
 	github.com/docker/cli v29.4.0+incompatible
 	github.com/docker/cli-docs-tool v0.11.0
-	github.com/docker/docker v28.5.2+incompatible
 	github.com/docker/go-units v0.5.0
 	github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
 	github.com/fsnotify/fsevents v0.2.0
@@ -73,6 +72,7 @@ require (
 	github.com/containerd/typeurl/v2 v2.2.3 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
 	github.com/docker/distribution v2.8.3+incompatible // indirect
+	github.com/docker/docker v28.5.2+incompatible // indirect
 	github.com/docker/docker-credential-helpers v0.9.5 // indirect
 	github.com/docker/go-connections v0.6.0 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect

+ 1 - 1
internal/locker/pidfile_unix.go

@@ -21,7 +21,7 @@ package locker
 import (
 	"os"
 
-	"github.com/docker/docker/pkg/pidfile"
+	"github.com/docker/compose/v5/internal/pidfile"
 )
 
 func (f *Pidfile) Lock() error {

+ 1 - 1
internal/locker/pidfile_windows.go

@@ -21,7 +21,7 @@ package locker
 import (
 	"os"
 
-	"github.com/docker/docker/pkg/pidfile"
+	"github.com/docker/compose/v5/internal/pidfile"
 	"github.com/mitchellh/go-ps"
 )
 

+ 67 - 0
internal/pidfile/pidfile.go

@@ -0,0 +1,67 @@
+/*
+   Copyright 2025 Docker Compose CLI 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 pidfile provides helper functions to create and remove PID files.
+// A PID file is usually a file used to store the process ID of a running
+// process.
+//
+// This is a temporary copy of github.com/moby/moby/v2/pkg/pidfile, and
+// should be replaced once pidfile is available as a standalone module.
+package pidfile
+
+import (
+	"bytes"
+	"fmt"
+	"os"
+	"strconv"
+)
+
+// Read reads the "PID file" at path, and returns the PID if it contains a
+// valid PID of a running process, or 0 otherwise. It returns an error when
+// failing to read the file, or if the file doesn't exist, but malformed content
+// is ignored. Consumers should therefore check if the returned PID is a non-zero
+// value before use.
+func Read(path string) (pid int, _ error) {
+	pidByte, err := os.ReadFile(path)
+	if err != nil {
+		return 0, err
+	}
+	pid, err = strconv.Atoi(string(bytes.TrimSpace(pidByte)))
+	if err != nil {
+		return 0, nil
+	}
+	if pid != 0 && alive(pid) {
+		return pid, nil
+	}
+	return 0, nil
+}
+
+// Write writes a "PID file" at the specified path. It returns an error if the
+// file exists and contains a valid PID of a running process, or when failing
+// to write the file.
+func Write(path string, pid int) error {
+	if pid < 1 {
+		return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid)
+	}
+	oldPID, err := Read(path)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+	if oldPID != 0 {
+		return fmt.Errorf("process with PID %d is still running", oldPID)
+	}
+	return os.WriteFile(path, []byte(strconv.Itoa(pid)), 0o644)
+}

+ 42 - 0
internal/pidfile/pidfile_unix.go

@@ -0,0 +1,42 @@
+//go:build !windows
+
+/*
+   Copyright 2025 Docker Compose CLI 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 pidfile
+
+import (
+	"errors"
+	"os"
+	"runtime"
+	"strconv"
+
+	"golang.org/x/sys/unix"
+)
+
+func alive(pid int) bool {
+	if pid < 1 {
+		return false
+	}
+	switch runtime.GOOS {
+	case "darwin":
+		err := unix.Kill(pid, 0)
+		return err == nil || errors.Is(err, unix.EPERM)
+	default:
+		_, err := os.Stat("/proc/" + strconv.Itoa(pid))
+		return err == nil
+	}
+}

+ 38 - 0
internal/pidfile/pidfile_windows.go

@@ -0,0 +1,38 @@
+//go:build windows
+
+/*
+   Copyright 2025 Docker Compose CLI 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 pidfile
+
+import "golang.org/x/sys/windows"
+
+func alive(pid int) bool {
+	if pid < 1 {
+		return false
+	}
+	h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
+	if err != nil {
+		return false
+	}
+	var c uint32
+	err = windows.GetExitCodeProcess(h, &c)
+	_ = windows.CloseHandle(h)
+	if err != nil {
+		return c == uint32(windows.STATUS_PENDING)
+	}
+	return true
+}

+ 56 - 3
pkg/compose/logs_test.go

@@ -17,13 +17,16 @@
 package compose
 
 import (
+	"bytes"
+	"encoding/binary"
+	"errors"
 	"io"
 	"strings"
 	"sync"
 	"testing"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/pkg/stdcopy"
+	"github.com/moby/moby/api/pkg/stdcopy"
 	containerType "github.com/moby/moby/api/types/container"
 	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
@@ -33,6 +36,56 @@ import (
 	compose "github.com/docker/compose/v5/pkg/api"
 )
 
+// newStdWriter is copied from github.com/moby/moby/daemon/internal/stdcopymux
+// because NewStdWriter was moved to a daemon-internal package in moby v2 and
+// is no longer publicly importable. We need it in tests to produce multiplexed
+// streams that stdcopy.StdCopy can demultiplex.
+
+const (
+	stdWriterPrefixLen = 8
+	stdWriterFdIndex   = 0
+	stdWriterSizeIndex = 4
+)
+
+var bufPool = &sync.Pool{New: func() any { return bytes.NewBuffer(nil) }}
+
+type stdWriter struct {
+	io.Writer
+	prefix byte
+}
+
+func (w *stdWriter) Write(p []byte) (int, error) {
+	if w == nil || w.Writer == nil {
+		return 0, errors.New("writer not instantiated")
+	}
+	if p == nil {
+		return 0, nil
+	}
+
+	header := [stdWriterPrefixLen]byte{stdWriterFdIndex: w.prefix}
+	binary.BigEndian.PutUint32(header[stdWriterSizeIndex:], uint32(len(p)))
+	buf := bufPool.Get().(*bytes.Buffer)
+	buf.Write(header[:])
+	buf.Write(p)
+
+	n, err := w.Writer.Write(buf.Bytes())
+	n -= stdWriterPrefixLen
+	if n < 0 {
+		n = 0
+	}
+
+	buf.Reset()
+	bufPool.Put(buf)
+	return n, err
+}
+
+func newStdWriter(w io.Writer, streamType stdcopy.StdType) io.Writer {
+	return &stdWriter{
+		Writer: w,
+		prefix: byte(streamType),
+	}
+}
+
 func TestComposeService_Logs_Demux(t *testing.T) {
 	mockCtrl := gomock.NewController(t)
 	defer mockCtrl.Finish()
@@ -68,8 +121,8 @@ func TestComposeService_Logs_Demux(t *testing.T) {
 		_ = c1Reader.Close()
 		_ = c1Writer.Close()
 	})
-	c1Stdout := stdcopy.NewStdWriter(c1Writer, stdcopy.Stdout)
-	c1Stderr := stdcopy.NewStdWriter(c1Writer, stdcopy.Stderr)
+	c1Stdout := newStdWriter(c1Writer, stdcopy.Stdout)
+	c1Stderr := newStdWriter(c1Writer, stdcopy.Stderr)
 	go func() {
 		_, err := c1Stdout.Write([]byte("hello stdout\n"))
 		assert.NilError(t, err, "Writing to fake stdout")

+ 1 - 1
pkg/compose/model.go

@@ -29,7 +29,7 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/errdefs"
 	"github.com/docker/cli/cli-plugins/manager"
-	"github.com/docker/docker/api/types/versions"
+	"github.com/moby/moby/client/pkg/versions"
 	"github.com/spf13/cobra"
 	"golang.org/x/sync/errgroup"