Skip to content

Commit ba417e4

Browse files
committed
use new moby/moby modules instead of docker/docker dependency
Signed-off-by: Guillaume Lours <[email protected]>
1 parent 9085f7b commit ba417e4

File tree

8 files changed

+207
-7
lines changed

8 files changed

+207
-7
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ require (
1818
github.com/docker/buildx v0.33.0
1919
github.com/docker/cli v29.4.0+incompatible
2020
github.com/docker/cli-docs-tool v0.11.0
21-
github.com/docker/docker v28.5.2+incompatible
2221
github.com/docker/go-units v0.5.0
2322
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
2423
github.com/fsnotify/fsevents v0.2.0
@@ -73,6 +72,7 @@ require (
7372
github.com/containerd/typeurl/v2 v2.2.3 // indirect
7473
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
7574
github.com/docker/distribution v2.8.3+incompatible // indirect
75+
github.com/docker/docker v28.5.2+incompatible // indirect
7676
github.com/docker/docker-credential-helpers v0.9.5 // indirect
7777
github.com/docker/go-connections v0.6.0 // indirect
7878
github.com/felixge/httpsnoop v1.0.4 // indirect

internal/locker/pidfile_unix.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ package locker
2121
import (
2222
"os"
2323

24-
"github.com/docker/docker/pkg/pidfile"
24+
"github.com/docker/compose/v5/internal/pidfile"
2525
)
2626

2727
func (f *Pidfile) Lock() error {

internal/locker/pidfile_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ package locker
2121
import (
2222
"os"
2323

24-
"github.com/docker/docker/pkg/pidfile"
24+
"github.com/docker/compose/v5/internal/pidfile"
2525
"github.com/mitchellh/go-ps"
2626
)
2727

internal/pidfile/pidfile.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright 2025 Docker Compose CLI authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package pidfile provides helper functions to create and remove PID files.
18+
// A PID file is usually a file used to store the process ID of a running
19+
// process.
20+
//
21+
// This is a temporary copy of github.com/moby/moby/v2/pkg/pidfile, and
22+
// should be replaced once pidfile is available as a standalone module.
23+
package pidfile
24+
25+
import (
26+
"bytes"
27+
"fmt"
28+
"os"
29+
"strconv"
30+
)
31+
32+
// Read reads the "PID file" at path, and returns the PID if it contains a
33+
// valid PID of a running process, or 0 otherwise. It returns an error when
34+
// failing to read the file, or if the file doesn't exist, but malformed content
35+
// is ignored. Consumers should therefore check if the returned PID is a non-zero
36+
// value before use.
37+
func Read(path string) (pid int, _ error) {
38+
pidByte, err := os.ReadFile(path)
39+
if err != nil {
40+
return 0, err
41+
}
42+
pid, err = strconv.Atoi(string(bytes.TrimSpace(pidByte)))
43+
if err != nil {
44+
return 0, nil
45+
}
46+
if pid != 0 && alive(pid) {
47+
return pid, nil
48+
}
49+
return 0, nil
50+
}
51+
52+
// Write writes a "PID file" at the specified path. It returns an error if the
53+
// file exists and contains a valid PID of a running process, or when failing
54+
// to write the file.
55+
func Write(path string, pid int) error {
56+
if pid < 1 {
57+
return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid)
58+
}
59+
oldPID, err := Read(path)
60+
if err != nil && !os.IsNotExist(err) {
61+
return err
62+
}
63+
if oldPID != 0 {
64+
return fmt.Errorf("process with PID %d is still running", oldPID)
65+
}
66+
return os.WriteFile(path, []byte(strconv.Itoa(pid)), 0o644)
67+
}

internal/pidfile/pidfile_unix.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//go:build !windows
2+
3+
/*
4+
Copyright 2025 Docker Compose CLI authors
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package pidfile
20+
21+
import (
22+
"errors"
23+
"os"
24+
"runtime"
25+
"strconv"
26+
27+
"golang.org/x/sys/unix"
28+
)
29+
30+
func alive(pid int) bool {
31+
if pid < 1 {
32+
return false
33+
}
34+
switch runtime.GOOS {
35+
case "darwin":
36+
err := unix.Kill(pid, 0)
37+
return err == nil || errors.Is(err, unix.EPERM)
38+
default:
39+
_, err := os.Stat("/proc/" + strconv.Itoa(pid))
40+
return err == nil
41+
}
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//go:build windows
2+
3+
/*
4+
Copyright 2025 Docker Compose CLI authors
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package pidfile
20+
21+
import "golang.org/x/sys/windows"
22+
23+
func alive(pid int) bool {
24+
if pid < 1 {
25+
return false
26+
}
27+
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
28+
if err != nil {
29+
return false
30+
}
31+
var c uint32
32+
err = windows.GetExitCodeProcess(h, &c)
33+
_ = windows.CloseHandle(h)
34+
if err != nil {
35+
return c == uint32(windows.STATUS_PENDING)
36+
}
37+
return true
38+
}

pkg/compose/logs_test.go

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package compose
1818

1919
import (
20+
"bytes"
21+
"encoding/binary"
22+
"errors"
2023
"io"
2124
"strings"
2225
"sync"
2326
"testing"
2427

2528
"github.com/compose-spec/compose-go/v2/types"
26-
"github.com/docker/docker/pkg/stdcopy"
29+
"github.com/moby/moby/api/pkg/stdcopy"
2730
containerType "github.com/moby/moby/api/types/container"
2831
"github.com/moby/moby/client"
2932
"go.uber.org/mock/gomock"
@@ -33,6 +36,56 @@ import (
3336
compose "github.com/docker/compose/v5/pkg/api"
3437
)
3538

39+
// newStdWriter is copied from github.com/moby/moby/daemon/internal/stdcopymux
40+
// because NewStdWriter was moved to a daemon-internal package in moby v2 and
41+
// is no longer publicly importable. We need it in tests to produce multiplexed
42+
// streams that stdcopy.StdCopy can demultiplex.
43+
44+
const (
45+
stdWriterPrefixLen = 8
46+
stdWriterFdIndex = 0
47+
stdWriterSizeIndex = 4
48+
)
49+
50+
var bufPool = &sync.Pool{New: func() any { return bytes.NewBuffer(nil) }}
51+
52+
type stdWriter struct {
53+
io.Writer
54+
prefix byte
55+
}
56+
57+
func (w *stdWriter) Write(p []byte) (int, error) {
58+
if w == nil || w.Writer == nil {
59+
return 0, errors.New("writer not instantiated")
60+
}
61+
if p == nil {
62+
return 0, nil
63+
}
64+
65+
header := [stdWriterPrefixLen]byte{stdWriterFdIndex: w.prefix}
66+
binary.BigEndian.PutUint32(header[stdWriterSizeIndex:], uint32(len(p)))
67+
buf := bufPool.Get().(*bytes.Buffer)
68+
buf.Write(header[:])
69+
buf.Write(p)
70+
71+
n, err := w.Writer.Write(buf.Bytes())
72+
n -= stdWriterPrefixLen
73+
if n < 0 {
74+
n = 0
75+
}
76+
77+
buf.Reset()
78+
bufPool.Put(buf)
79+
return n, err
80+
}
81+
82+
func newStdWriter(w io.Writer, streamType stdcopy.StdType) io.Writer {
83+
return &stdWriter{
84+
Writer: w,
85+
prefix: byte(streamType),
86+
}
87+
}
88+
3689
func TestComposeService_Logs_Demux(t *testing.T) {
3790
mockCtrl := gomock.NewController(t)
3891
defer mockCtrl.Finish()
@@ -68,8 +121,8 @@ func TestComposeService_Logs_Demux(t *testing.T) {
68121
_ = c1Reader.Close()
69122
_ = c1Writer.Close()
70123
})
71-
c1Stdout := stdcopy.NewStdWriter(c1Writer, stdcopy.Stdout)
72-
c1Stderr := stdcopy.NewStdWriter(c1Writer, stdcopy.Stderr)
124+
c1Stdout := newStdWriter(c1Writer, stdcopy.Stdout)
125+
c1Stderr := newStdWriter(c1Writer, stdcopy.Stderr)
73126
go func() {
74127
_, err := c1Stdout.Write([]byte("hello stdout\n"))
75128
assert.NilError(t, err, "Writing to fake stdout")

pkg/compose/model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"github.com/compose-spec/compose-go/v2/types"
3030
"github.com/containerd/errdefs"
3131
"github.com/docker/cli/cli-plugins/manager"
32-
"github.com/docker/docker/api/types/versions"
32+
"github.com/moby/moby/client/pkg/versions"
3333
"github.com/spf13/cobra"
3434
"golang.org/x/sync/errgroup"
3535

0 commit comments

Comments
 (0)