mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-07-13 00:52:01 -04:00
Merge pull request #3023 from opencloud-eu/dependabot/go_modules/github.com/testcontainers/testcontainers-go/modules/opensearch-0.43.0
build(deps): bump github.com/testcontainers/testcontainers-go/modules/opensearch from 0.42.0 to 0.43.0
This commit is contained in:
8
go.mod
8
go.mod
@@ -82,8 +82,8 @@ require (
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/test-go/testify v1.1.4
|
||||
github.com/testcontainers/testcontainers-go v0.42.0
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.42.0
|
||||
github.com/testcontainers/testcontainers-go v0.43.0
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0
|
||||
github.com/theckman/yacspin v0.13.12
|
||||
github.com/thejerf/suture/v4 v4.0.6
|
||||
github.com/tidwall/gjson v1.19.0
|
||||
@@ -292,7 +292,7 @@ require (
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/go-archive v0.2.0 // indirect
|
||||
github.com/moby/moby/api v1.54.1 // indirect
|
||||
github.com/moby/moby/api v1.54.2 // indirect
|
||||
github.com/moby/moby/client v0.4.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.1 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
@@ -347,7 +347,7 @@ require (
|
||||
github.com/sethvargo/go-diceware v0.5.0 // indirect
|
||||
github.com/sethvargo/go-password v0.3.1 // indirect
|
||||
github.com/shamaton/msgpack/v2 v2.4.1 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.26.3 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.26.5 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@@ -866,8 +866,8 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
|
||||
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
|
||||
github.com/moby/moby/api v1.54.1 h1:TqVzuJkOLsgLDDwNLmYqACUuTehOHRGKiPhvH8V3Nn4=
|
||||
github.com/moby/moby/api v1.54.1/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
|
||||
github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg=
|
||||
github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
|
||||
github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw=
|
||||
github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g=
|
||||
github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U=
|
||||
@@ -1115,8 +1115,8 @@ github.com/shamaton/msgpack/v2 v2.4.1 h1:JtJ141QoQ3NqgPDsjq2v9VXlaON8SiQOwEaoNLE
|
||||
github.com/shamaton/msgpack/v2 v2.4.1/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil/v4 v4.26.3 h1:2ESdQt90yU3oXF/CdOlRCJxrP+Am1aBYubTMTfxJ1qc=
|
||||
github.com/shirou/gopsutil/v4 v4.26.3/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
|
||||
github.com/shirou/gopsutil/v4 v4.26.5 h1:RPcBXkpz7kOj9PqGFQOlBPZHsyaPvPVQc098y9RmCNM=
|
||||
github.com/shirou/gopsutil/v4 v4.26.5/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
@@ -1192,10 +1192,10 @@ github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhg
|
||||
github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
|
||||
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
|
||||
github.com/testcontainers/testcontainers-go v0.42.0 h1:He3IhTzTZOygSXLJPMX7n44XtK+qhjat1nI9cneBbUY=
|
||||
github.com/testcontainers/testcontainers-go v0.42.0/go.mod h1:vZjdY1YmUA1qEForxOIOazfsrdyORJAbhi0bp8plN30=
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.42.0 h1:lXPr5NypYR0O8qcej+JQfsQTOTc3CRv+c4wz3VbBFLI=
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.42.0/go.mod h1:KJ+m9onB785g9VDRDuhvUvsbkRjnFp3Uz+CHoHpPieA=
|
||||
github.com/testcontainers/testcontainers-go v0.43.0 h1:oEQx5MW2DGd9z3AeEQfB2lPM0eLs7ztyaGRu75bFo5A=
|
||||
github.com/testcontainers/testcontainers-go v0.43.0/go.mod h1:+VxkT2NQnKOZPKi6praMuMKYHYyOGXr0XSBSlSMCzFo=
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0 h1:a1ipjF7d/VxPX1dgVPIk4F+t6YkgMbE2OtBuRQCHJt8=
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0/go.mod h1:OWSeUDiGMUy30iMsAltIJIo9uh/CleLv6KyxjYOsgR8=
|
||||
github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o=
|
||||
github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U=
|
||||
github.com/theckman/yacspin v0.13.12 h1:CdZ57+n0U6JMuh2xqjnjRq5Haj6v1ner2djtLQRzJr4=
|
||||
|
||||
67
vendor/github.com/shirou/gopsutil/v4/cpu/cpu_windows.go
generated
vendored
67
vendor/github.com/shirou/gopsutil/v4/cpu/cpu_windows.go
generated
vendored
@@ -25,6 +25,7 @@ var (
|
||||
procGetLogicalProcessorInformationEx = common.Modkernel32.NewProc("GetLogicalProcessorInformationEx")
|
||||
procGetSystemFirmwareTable = common.Modkernel32.NewProc("GetSystemFirmwareTable")
|
||||
procCallNtPowerInformation = common.ModPowrProf.NewProc("CallNtPowerInformation")
|
||||
procGetActiveProcessorGroupCount = common.Modkernel32.NewProc("GetActiveProcessorGroupCount")
|
||||
)
|
||||
|
||||
type win32_Processor struct { //nolint:revive //FIXME
|
||||
@@ -263,6 +264,21 @@ func perCPUTimes() ([]TimesStat, error) {
|
||||
|
||||
// makes call to Windows API function to retrieve performance information for each core
|
||||
func perfInfo() ([]win32_SystemProcessorPerformanceInformation, error) {
|
||||
// On hosts with more than 64 logical CPUs Windows splits CPUs into Processor Groups
|
||||
// (up to 64 logical CPUs per group). The non-Ex NtQuerySystemInformation only returns
|
||||
// data for the calling thread's group, so whenever the Ex variant is available we
|
||||
// iterate every active group and concatenate the results. See issue #887.
|
||||
if common.ProcNtQuerySystemInformationEx.Find() == nil {
|
||||
return perfInfoAllGroups()
|
||||
}
|
||||
return perfInfoSingleGroup()
|
||||
}
|
||||
|
||||
// perfInfoSingleGroup queries SystemProcessorPerformanceInformation via the non-Ex
|
||||
// NtQuerySystemInformation call. This is the legacy fallback for environments where
|
||||
// NtQuerySystemInformationEx cannot be resolved; it only returns data for the calling
|
||||
// thread's processor group.
|
||||
func perfInfoSingleGroup() ([]win32_SystemProcessorPerformanceInformation, error) {
|
||||
// Make maxResults large for safety.
|
||||
// We can't invoke the api call with a results array that's too small.
|
||||
// If we have more than 2056 cores on a single host, then it's probably the future.
|
||||
@@ -286,16 +302,61 @@ func perfInfo() ([]win32_SystemProcessorPerformanceInformation, error) {
|
||||
|
||||
// check return code for errors
|
||||
if retCode != 0 {
|
||||
return nil, fmt.Errorf("call to NtQuerySystemInformation returned %d. err: %s", retCode, err.Error())
|
||||
return nil, fmt.Errorf("call to NtQuerySystemInformation returned 0x%x: %w", retCode, err)
|
||||
}
|
||||
|
||||
// calculate the number of returned elements based on the returned size
|
||||
numReturnedElements := retSize / win32_SystemProcessorPerformanceInfoSize
|
||||
|
||||
// trim results to the number of returned elements
|
||||
resultBuffer = resultBuffer[:numReturnedElements]
|
||||
return resultBuffer[:numReturnedElements], nil
|
||||
}
|
||||
|
||||
return resultBuffer, nil
|
||||
// perfInfoAllGroups queries SystemProcessorPerformanceInformation for every active
|
||||
// processor group via NtQuerySystemInformationEx and concatenates the results. The
|
||||
// group index is passed as the InputBuffer per the Ex calling convention documented at
|
||||
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/queryex.htm
|
||||
func perfInfoAllGroups() ([]win32_SystemProcessorPerformanceInformation, error) {
|
||||
// GetActiveProcessorGroupCount returns 0 only on failure; propagate the error
|
||||
// rather than silently defaulting to a single group and returning partial data.
|
||||
r, _, callErr := procGetActiveProcessorGroupCount.Call()
|
||||
if r == 0 {
|
||||
return nil, fmt.Errorf("GetActiveProcessorGroupCount returned 0: %w", callErr)
|
||||
}
|
||||
groupCount := uint16(r)
|
||||
|
||||
var result []win32_SystemProcessorPerformanceInformation
|
||||
for g := uint16(0); g < groupCount; g++ {
|
||||
numLP := windows.GetActiveProcessorCount(g)
|
||||
if numLP == 0 {
|
||||
return nil, fmt.Errorf("GetActiveProcessorCount returned 0 for processor group %d", g)
|
||||
}
|
||||
// buffer sized exactly for this group's logical CPU count
|
||||
buf := make([]win32_SystemProcessorPerformanceInformation, numLP)
|
||||
bufSize := uintptr(win32_SystemProcessorPerformanceInfoSize) * uintptr(numLP)
|
||||
var retSize uint32
|
||||
// InputBuffer is a USHORT (2 bytes) holding the target processor group index.
|
||||
group := g
|
||||
retCode, _, err := common.ProcNtQuerySystemInformationEx.Call(
|
||||
win32_SystemProcessorPerformanceInformationClass, // System Information Class -> SystemProcessorPerformanceInformation
|
||||
uintptr(unsafe.Pointer(&group)), // InputBuffer: pointer to USHORT group index
|
||||
unsafe.Sizeof(group), // InputBufferLength: sizeof(USHORT) = 2
|
||||
uintptr(unsafe.Pointer(&buf[0])), // pointer to first element in result buffer
|
||||
bufSize, // size of the buffer in memory
|
||||
uintptr(unsafe.Pointer(&retSize)), // pointer to the size of the returned results the windows proc will set this
|
||||
)
|
||||
if retCode != 0 {
|
||||
return nil, fmt.Errorf("call to NtQuerySystemInformationEx(group=%d) returned 0x%x: %w", g, retCode, err)
|
||||
}
|
||||
// Guard against a retSize that is not a whole number of entries or exceeds
|
||||
// the allocated buffer (e.g. CPU hot-add racing with GetActiveProcessorCount).
|
||||
if retSize%win32_SystemProcessorPerformanceInfoSize != 0 || uintptr(retSize) > bufSize {
|
||||
return nil, fmt.Errorf("NtQuerySystemInformationEx(group=%d) returned unexpected retSize=%d (bufSize=%d)", g, retSize, bufSize)
|
||||
}
|
||||
n := retSize / win32_SystemProcessorPerformanceInfoSize
|
||||
result = append(result, buf[:n]...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SystemInfo is an equivalent representation of SYSTEM_INFO in the Windows API.
|
||||
|
||||
1
vendor/github.com/shirou/gopsutil/v4/internal/common/common_windows.go
generated
vendored
1
vendor/github.com/shirou/gopsutil/v4/internal/common/common_windows.go
generated
vendored
@@ -73,6 +73,7 @@ var (
|
||||
|
||||
ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes")
|
||||
ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
|
||||
ProcNtQuerySystemInformationEx = ModNt.NewProc("NtQuerySystemInformationEx")
|
||||
ProcRtlGetNativeSystemInformation = ModNt.NewProc("RtlGetNativeSystemInformation")
|
||||
ProcRtlNtStatusToDosError = ModNt.NewProc("RtlNtStatusToDosError")
|
||||
ProcNtQueryInformationProcess = ModNt.NewProc("NtQueryInformationProcess")
|
||||
|
||||
3
vendor/github.com/shirou/gopsutil/v4/mem/mem_netbsd.go
generated
vendored
3
vendor/github.com/shirou/gopsutil/v4/mem/mem_netbsd.go
generated
vendored
@@ -61,6 +61,7 @@ func SwapMemory() (*SwapMemoryStat, error) {
|
||||
return SwapMemoryWithContext(context.Background())
|
||||
}
|
||||
|
||||
// Reference: https://man.netbsd.org/swapctl.8
|
||||
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
|
||||
out, err := invoke.CommandWithContext(ctx, "swapctl", "-sk")
|
||||
if err != nil {
|
||||
@@ -71,7 +72,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
|
||||
var total, used, free uint64
|
||||
|
||||
_, err = fmt.Sscanf(line,
|
||||
"total: %d 1K-blocks allocated, %d used, %d available",
|
||||
"total: %d KBytes allocated, %d KBytes used, %d KBytes available",
|
||||
&total, &used, &free)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to parse swapctl output")
|
||||
|
||||
17
vendor/github.com/shirou/gopsutil/v4/net/net.go
generated
vendored
17
vendor/github.com/shirou/gopsutil/v4/net/net.go
generated
vendored
@@ -286,12 +286,25 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
|
||||
return IOCountersByFileWithContext(context.Background(), pernic, filename)
|
||||
}
|
||||
|
||||
// ProtoCounters returns network statistics for the entire system
|
||||
// ProtoCounters returns network statistics for the entire system.
|
||||
// If protocols is empty then all protocols are returned, otherwise
|
||||
// just the protocols in the list are returned.
|
||||
//
|
||||
// Available protocols:
|
||||
// [ip,icmp,icmpmsg,tcp,udp,udplite]
|
||||
// Not Implemented for FreeBSD, Windows, OpenBSD, Darwin
|
||||
//
|
||||
// Key naming contract:
|
||||
// The keys of the returned Stats map use MIB-II (RFC 1213) identifier
|
||||
// names — e.g. "InSegs", "OutSegs", "RetransSegs", "ActiveOpens",
|
||||
// "InDatagrams", "NoPorts". This contract was established by the
|
||||
// original Linux implementation, which sources its keys from
|
||||
// /proc/net/snmp (whose headers are MIB-II names). Per-platform
|
||||
// implementations are expected to map their native counter sources
|
||||
// (e.g. AIX `netstat -s`, BSD sysctl) to these MIB-II names.
|
||||
// Native counters that have no MIB-II equivalent are not exposed
|
||||
// through this API.
|
||||
//
|
||||
// Not Implemented for FreeBSD, Windows, OpenBSD, Darwin, Solaris.
|
||||
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
|
||||
return ProtoCountersWithContext(context.Background(), protocols)
|
||||
}
|
||||
|
||||
236
vendor/github.com/shirou/gopsutil/v4/net/net_aix.go
generated
vendored
236
vendor/github.com/shirou/gopsutil/v4/net/net_aix.go
generated
vendored
@@ -31,8 +31,240 @@ func ConntrackStatsWithContext(_ context.Context, _ bool) ([]ConntrackStat, erro
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ProtoCountersWithContext(_ context.Context, _ []string) ([]ProtoCountersStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
|
||||
out, err := invoke.CommandWithContext(ctx, "netstat", "-s")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseNetstatS(string(out), protocols)
|
||||
}
|
||||
|
||||
// parseNetstatS parses "netstat -s" output on AIX.
|
||||
//
|
||||
// Format:
|
||||
//
|
||||
// <proto>:
|
||||
// \t<count> <description>
|
||||
// \t\t<count> <sub-description>
|
||||
//
|
||||
// Descriptions containing parenthetical sub-counts (e.g. "(6302116893 bytes)")
|
||||
// are normalised by stripping the parenthetical before matching.
|
||||
func parseNetstatS(output string, protocols []string) ([]ProtoCountersStat, error) {
|
||||
var stats []ProtoCountersStat
|
||||
var currentProto string
|
||||
var currentStats map[string]int64
|
||||
|
||||
for _, line := range strings.Split(output, "\n") {
|
||||
// Protocol header: no leading whitespace, ends with ":"
|
||||
if line != "" && line[0] != '\t' {
|
||||
if currentProto != "" && len(currentStats) > 0 {
|
||||
if len(protocols) == 0 || common.StringsHas(protocols, currentProto) {
|
||||
stats = append(stats, ProtoCountersStat{
|
||||
Protocol: currentProto,
|
||||
Stats: currentStats,
|
||||
})
|
||||
}
|
||||
}
|
||||
currentProto = strings.TrimSuffix(strings.TrimSpace(line), ":")
|
||||
currentStats = make(map[string]int64)
|
||||
continue
|
||||
}
|
||||
|
||||
if currentProto == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Count leading tabs to track indentation depth (1 = top-level metric).
|
||||
depth := 0
|
||||
rest := line
|
||||
for rest != "" && rest[0] == '\t' {
|
||||
depth++
|
||||
rest = rest[1:]
|
||||
}
|
||||
if depth == 0 || rest == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Split "<number> <description>".
|
||||
spaceIdx := strings.IndexByte(rest, ' ')
|
||||
if spaceIdx <= 0 {
|
||||
continue
|
||||
}
|
||||
val, err := strconv.ParseInt(rest[:spaceIdx], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
// Normalise: remove parenthetical sub-counts like "(6302116893 bytes)".
|
||||
desc := normaliseNetstatDesc(strings.TrimSpace(rest[spaceIdx+1:]))
|
||||
|
||||
if key := aixProtoKey(currentProto, depth, desc); key != "" {
|
||||
currentStats[key] += val
|
||||
}
|
||||
}
|
||||
|
||||
if currentProto != "" && len(currentStats) > 0 {
|
||||
if len(protocols) == 0 || common.StringsHas(protocols, currentProto) {
|
||||
stats = append(stats, ProtoCountersStat{
|
||||
Protocol: currentProto,
|
||||
Stats: currentStats,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// normaliseNetstatDesc strips a single parenthetical from a netstat -s description,
|
||||
// e.g. "data packets (6302116893 bytes) retransmitted" → "data packets retransmitted".
|
||||
func normaliseNetstatDesc(s string) string {
|
||||
start := strings.Index(s, "(")
|
||||
if start == -1 {
|
||||
return s
|
||||
}
|
||||
end := strings.LastIndex(s, ")")
|
||||
if end < start {
|
||||
return s
|
||||
}
|
||||
return strings.Join(strings.Fields(s[:start]+s[end+1:]), " ")
|
||||
}
|
||||
|
||||
// aixProtoKey maps a normalised AIX netstat -s description to a ProtoCountersStat key.
|
||||
// depth is the tab-indentation level (1 = top-level line under the protocol header).
|
||||
// Returns "" for lines that should be ignored.
|
||||
func aixProtoKey(proto string, depth int, desc string) string {
|
||||
switch proto {
|
||||
case "tcp":
|
||||
return aixTCPKey(depth, desc)
|
||||
case "udp":
|
||||
return aixUDPKey(desc)
|
||||
case "ip":
|
||||
return aixIPKey(depth, desc)
|
||||
case "ipv6":
|
||||
return aixIPv6Key(depth, desc)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func aixTCPKey(depth int, desc string) string {
|
||||
switch {
|
||||
// Top-level totals — depth check avoids matching sub-lines like "N data packets sent".
|
||||
case depth == 1 && desc == "packets sent":
|
||||
return "OutSegs"
|
||||
case depth == 1 && desc == "packets received":
|
||||
return "InSegs"
|
||||
// Sub-line: "data packets NNN bytes retransmitted" → normalised "data packets retransmitted"
|
||||
case strings.Contains(desc, "retransmitted"):
|
||||
return "RetransSegs"
|
||||
case desc == "connection requests":
|
||||
return "ActiveOpens"
|
||||
case desc == "connection accepts":
|
||||
return "PassiveOpens"
|
||||
case desc == "embryonic connections dropped":
|
||||
return "AttemptFails"
|
||||
case strings.HasPrefix(desc, "discarded for bad checksums"):
|
||||
return "InCsumErrors"
|
||||
// Other input errors accumulate into InErrs.
|
||||
case strings.HasPrefix(desc, "discarded for bad header") ||
|
||||
strings.HasPrefix(desc, "discarded because packet too short"):
|
||||
return "InErrs"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func aixUDPKey(desc string) string {
|
||||
switch {
|
||||
case desc == "delivered":
|
||||
return "InDatagrams"
|
||||
// Both unicast and broadcast "dropped due to no socket" map to NoPorts.
|
||||
case strings.Contains(desc, "dropped due to no socket"):
|
||||
return "NoPorts"
|
||||
case desc == "bad checksums":
|
||||
return "InCsumErrors"
|
||||
case desc == "socket buffer overflows":
|
||||
return "RcvbufErrors"
|
||||
case desc == "datagrams output":
|
||||
return "OutDatagrams"
|
||||
case desc == "incomplete headers" || desc == "bad data length fields":
|
||||
return "InErrors"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func aixIPKey(depth int, desc string) string {
|
||||
switch {
|
||||
case desc == "total packets received":
|
||||
return "InReceives"
|
||||
// All header-error variants accumulate into InHdrErrors.
|
||||
case desc == "bad header checksums" ||
|
||||
desc == "with size smaller than minimum" ||
|
||||
desc == "with data size < data length" ||
|
||||
desc == "with header length < data size" ||
|
||||
desc == "with data length < header length" ||
|
||||
desc == "with bad options" ||
|
||||
desc == "with incorrect version number":
|
||||
return "InHdrErrors"
|
||||
case strings.Contains(desc, "unknown/unsupported protocol"):
|
||||
return "InUnknownProtos"
|
||||
case desc == "packets for this host":
|
||||
return "InDelivers"
|
||||
case depth == 1 && desc == "packets forwarded":
|
||||
return "ForwDatagrams"
|
||||
case desc == "packets sent from this host":
|
||||
return "OutRequests"
|
||||
case desc == "packets reassembled ok":
|
||||
return "ReasmOKs"
|
||||
case strings.HasPrefix(desc, "fragments dropped after timeout"):
|
||||
return "ReasmFails"
|
||||
case desc == "fragments received":
|
||||
return "ReasmReqds"
|
||||
case strings.HasPrefix(desc, "fragments dropped"):
|
||||
return "InDiscards"
|
||||
case desc == "fragments created":
|
||||
return "FragCreates"
|
||||
case desc == "output packets discarded due to no route":
|
||||
return "OutNoRoutes"
|
||||
case strings.HasPrefix(desc, "output packets dropped due to no bufs"):
|
||||
return "OutDiscards"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func aixIPv6Key(depth int, desc string) string {
|
||||
switch {
|
||||
case desc == "total packets received":
|
||||
return "InReceives"
|
||||
case desc == "with size smaller than minimum" ||
|
||||
desc == "with data size < data length" ||
|
||||
desc == "with incorrect version number" ||
|
||||
desc == "with illegal source":
|
||||
return "InHdrErrors"
|
||||
case strings.Contains(desc, "unknown/unsupported protocol"):
|
||||
return "InUnknownProtos"
|
||||
case desc == "input packets without enough memory":
|
||||
return "InDiscards"
|
||||
case desc == "packets for this host":
|
||||
return "InDelivers"
|
||||
case depth == 1 && desc == "packets forwarded":
|
||||
return "ForwDatagrams"
|
||||
case desc == "packets sent from this host":
|
||||
return "OutRequests"
|
||||
case desc == "packets reassembled ok":
|
||||
return "ReasmOKs"
|
||||
case strings.HasPrefix(desc, "fragments dropped after timeout"):
|
||||
return "ReasmFails"
|
||||
case desc == "fragments received":
|
||||
return "ReasmReqds"
|
||||
case strings.HasPrefix(desc, "fragments dropped"):
|
||||
return "InDiscards"
|
||||
case desc == "fragments created":
|
||||
return "FragCreates"
|
||||
case desc == "output packets discarded due to no route":
|
||||
return "OutNoRoutes"
|
||||
case strings.HasPrefix(desc, "output packets dropped due to no bufs") ||
|
||||
desc == "output packets without enough memory":
|
||||
return "OutDiscards"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func parseNetstatNetLine(line string) (ConnectionStat, error) {
|
||||
|
||||
47
vendor/github.com/shirou/gopsutil/v4/net/net_aix_nocgo.go
generated
vendored
47
vendor/github.com/shirou/gopsutil/v4/net/net_aix_nocgo.go
generated
vendored
@@ -78,6 +78,35 @@ func parseNetstatI(output string) ([]IOCountersStat, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// parseEntstat extracts BytesSent and BytesRecv from entstat output.
|
||||
// The entstat two-column Transmit/Receive format (including the "Bytes:"
|
||||
// line) has been stable across AIX 4.3 through 7.3 (over 25 years).
|
||||
// The output has a two-column layout with Transmit on the left and Receive
|
||||
// on the right, e.g.:
|
||||
//
|
||||
// Bytes: 3509236040 Bytes: 4547812126
|
||||
func parseEntstat(output string) (bytesSent, bytesRecv uint64) {
|
||||
for _, line := range strings.Split(output, "\n") {
|
||||
if !strings.Contains(line, "Bytes:") {
|
||||
continue
|
||||
}
|
||||
// Split on "Bytes:" to get: ["", " 3509236040 ", " 4547812126"]
|
||||
parts := strings.Split(line, "Bytes:")
|
||||
if len(parts) >= 2 {
|
||||
if v, err := strconv.ParseUint(strings.TrimSpace(parts[1]), 10, 64); err == nil {
|
||||
bytesSent = v
|
||||
}
|
||||
}
|
||||
if len(parts) >= 3 {
|
||||
if v, err := strconv.ParseUint(strings.TrimSpace(parts[2]), 10, 64); err == nil {
|
||||
bytesRecv = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
|
||||
out, err := invoke.CommandWithContext(ctx, "netstat", "-idn")
|
||||
if err != nil {
|
||||
@@ -88,6 +117,24 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Populate BytesSent/BytesRecv via entstat for each interface.
|
||||
// entstat only works on hardware/virtual ethernet adapters; it fails
|
||||
// on loopback (lo0) with errno 19, which is silently skipped. Errors
|
||||
// on other interfaces are propagated since they indicate a real problem.
|
||||
for i := range iocounters {
|
||||
entOut, err := invoke.CommandWithContext(ctx, "entstat", iocounters[i].Name)
|
||||
if err != nil {
|
||||
// entstat fails on loopback (lo0) with errno 19 — this is expected.
|
||||
// For other interfaces, propagate the error.
|
||||
if iocounters[i].Name == "lo0" {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
iocounters[i].BytesSent, iocounters[i].BytesRecv = parseEntstat(string(entOut))
|
||||
}
|
||||
|
||||
if !pernic {
|
||||
return getIOCountersAll(iocounters), nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/shirou/gopsutil/v4/net/net_fallback.go
generated
vendored
2
vendor/github.com/shirou/gopsutil/v4/net/net_fallback.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//go:build !aix && !darwin && !linux && !freebsd && !openbsd && !windows && !solaris
|
||||
//go:build !aix && !darwin && !linux && !freebsd && !openbsd && !windows && !solaris && !netbsd
|
||||
|
||||
package net
|
||||
|
||||
|
||||
3
vendor/github.com/shirou/gopsutil/v4/net/net_linux.go
generated
vendored
3
vendor/github.com/shirou/gopsutil/v4/net/net_linux.go
generated
vendored
@@ -69,6 +69,9 @@ func IOCountersByFileWithContext(_ context.Context, pernic bool, filename string
|
||||
}
|
||||
|
||||
fields := strings.Fields(strings.TrimSpace(statsPart))
|
||||
if len(fields) < 13 {
|
||||
continue
|
||||
}
|
||||
bytesRecv, err := strconv.ParseUint(fields[0], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
|
||||
353
vendor/github.com/shirou/gopsutil/v4/net/net_netbsd.go
generated
vendored
Normal file
353
vendor/github.com/shirou/gopsutil/v4/net/net_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//go:build netbsd
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/internal/common"
|
||||
)
|
||||
|
||||
var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`)
|
||||
|
||||
// parseNetstat parses the output of "netstat -inb" (mode "inb") or
|
||||
// "netstat -ind" (mode "ind") and merges results into iocs.
|
||||
//
|
||||
// NetBSD netstat column layout (0-indexed fields after strings.Fields):
|
||||
//
|
||||
// -inb with Address (6 fields): Name Mtu Network Address Ibytes Obytes
|
||||
// -inb without Address (5 fields): Name Mtu Network Ibytes Obytes
|
||||
//
|
||||
// -ind with Address (11 fields): Name Mtu Network Address Ipkts Ierrs Idrops Opkts Oerrs Colls Odrops
|
||||
// -ind without Address (10 fields): Name Mtu Network Ipkts Ierrs Idrops Opkts Oerrs Colls Odrops
|
||||
//
|
||||
// The Address field is present for non-loopback interfaces and absent for
|
||||
// loopback (lo0). We detect this via field count and set base accordingly.
|
||||
//
|
||||
// Reference: https://man.netbsd.org/netstat.1
|
||||
func parseNetstat(output, mode string, iocs map[string]IOCountersStat) error {
|
||||
// Minimum field counts when Address is absent.
|
||||
minFields := map[string]int{
|
||||
"inb": 5,
|
||||
"ind": 10,
|
||||
}
|
||||
// Field count when Address is present (base = 1).
|
||||
addrFields := map[string]int{
|
||||
"inb": 6,
|
||||
"ind": 11,
|
||||
}
|
||||
|
||||
seen := make([]string, 0)
|
||||
|
||||
for _, line := range strings.Split(output, "\n") {
|
||||
values := strings.Fields(line)
|
||||
if len(values) < 1 || values[0] == "Name" {
|
||||
continue
|
||||
}
|
||||
if common.StringsHas(seen, values[0]) {
|
||||
continue
|
||||
}
|
||||
if len(values) < minFields[mode] {
|
||||
continue
|
||||
}
|
||||
|
||||
base := 0
|
||||
if len(values) >= addrFields[mode] {
|
||||
base = 1
|
||||
}
|
||||
|
||||
seen = append(seen, values[0])
|
||||
|
||||
n, present := iocs[values[0]]
|
||||
if !present {
|
||||
n = IOCountersStat{Name: values[0]}
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case "inb":
|
||||
recv, err := parseUint(values[base+3])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sent, err := parseUint(values[base+4])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.BytesRecv = recv
|
||||
n.BytesSent = sent
|
||||
|
||||
case "ind":
|
||||
// Ipkts Ierrs Idrops Opkts Oerrs Colls Odrops
|
||||
pktsRecv, err := parseUint(values[base+3])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
errin, err := parseUint(values[base+4])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dropin, err := parseUint(values[base+5])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pktsSent, err := parseUint(values[base+6])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
errout, err := parseUint(values[base+7])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// values[base+8] = Colls (not mapped to IOCountersStat)
|
||||
dropout, err := parseUint(values[base+9])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.PacketsRecv = pktsRecv
|
||||
n.Errin = errin
|
||||
n.Dropin = dropin
|
||||
n.PacketsSent = pktsSent
|
||||
n.Errout = errout
|
||||
n.Dropout = dropout
|
||||
}
|
||||
|
||||
iocs[n.Name] = n
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseUint(s string) (uint64, error) {
|
||||
if s == "-" {
|
||||
return 0, nil
|
||||
}
|
||||
return strconv.ParseUint(s, 10, 64)
|
||||
}
|
||||
|
||||
// Deprecated: use process.PidsWithContext instead
|
||||
func PidsWithContext(_ context.Context) ([]int32, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
|
||||
netstat, err := exec.LookPath("netstat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
outBytes, err := invoke.CommandWithContext(ctx, netstat, "-inb")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outPackets, err := invoke.CommandWithContext(ctx, netstat, "-ind")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iocs := make(map[string]IOCountersStat)
|
||||
|
||||
if err := parseNetstat(string(outBytes), "inb", iocs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := parseNetstat(string(outPackets), "ind", iocs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make([]IOCountersStat, 0, len(iocs))
|
||||
for _, ioc := range iocs {
|
||||
ret = append(ret, ioc)
|
||||
}
|
||||
|
||||
if !pernic {
|
||||
return getIOCountersAll(ret), nil
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func IOCountersByFileWithContext(ctx context.Context, pernic bool, _ string) ([]IOCountersStat, error) {
|
||||
return IOCountersWithContext(ctx, pernic)
|
||||
}
|
||||
|
||||
func FilterCountersWithContext(_ context.Context) ([]FilterStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ConntrackStatsWithContext(_ context.Context, _ bool) ([]ConntrackStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ProtoCountersWithContext(_ context.Context, _ []string) ([]ProtoCountersStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func parseNetstatLine(line string) (ConnectionStat, error) {
|
||||
f := strings.Fields(line)
|
||||
if len(f) < 5 {
|
||||
return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
|
||||
}
|
||||
|
||||
var netType, netFamily uint32
|
||||
switch f[0] {
|
||||
case "tcp":
|
||||
netType = syscall.SOCK_STREAM
|
||||
netFamily = syscall.AF_INET
|
||||
case "udp":
|
||||
netType = syscall.SOCK_DGRAM
|
||||
netFamily = syscall.AF_INET
|
||||
case "tcp6":
|
||||
netType = syscall.SOCK_STREAM
|
||||
netFamily = syscall.AF_INET6
|
||||
case "udp6":
|
||||
netType = syscall.SOCK_DGRAM
|
||||
netFamily = syscall.AF_INET6
|
||||
default:
|
||||
return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[0])
|
||||
}
|
||||
|
||||
laddr, raddr, err := parseNetstatAddr(f[3], f[4], netFamily)
|
||||
if err != nil {
|
||||
return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s %s", f[3], f[4])
|
||||
}
|
||||
|
||||
n := ConnectionStat{
|
||||
Fd: uint32(0), // not supported
|
||||
Family: uint32(netFamily),
|
||||
Type: uint32(netType),
|
||||
Laddr: laddr,
|
||||
Raddr: raddr,
|
||||
Pid: int32(0), // not supported
|
||||
}
|
||||
if len(f) == 6 {
|
||||
n.Status = f[5]
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func parseAddr(l string, family uint32) (Addr, error) {
|
||||
matches := portMatch.FindStringSubmatch(l)
|
||||
if matches == nil {
|
||||
return Addr{}, fmt.Errorf("wrong addr, %s", l)
|
||||
}
|
||||
host := matches[1]
|
||||
port := matches[2]
|
||||
if host == "*" {
|
||||
switch family {
|
||||
case syscall.AF_INET:
|
||||
host = "0.0.0.0"
|
||||
case syscall.AF_INET6:
|
||||
host = "::"
|
||||
default:
|
||||
return Addr{}, fmt.Errorf("unknown family, %d", family)
|
||||
}
|
||||
}
|
||||
lport, err := strconv.ParseInt(port, 10, 32)
|
||||
if err != nil {
|
||||
return Addr{}, err
|
||||
}
|
||||
return Addr{IP: host, Port: uint32(lport)}, nil
|
||||
}
|
||||
|
||||
func parseNetstatAddr(local, remote string, family uint32) (laddr, raddr Addr, err error) {
|
||||
laddr, err = parseAddr(local, family)
|
||||
if err != nil {
|
||||
return laddr, raddr, err
|
||||
}
|
||||
if remote != "*.*" {
|
||||
raddr, err = parseAddr(remote, family)
|
||||
if err != nil {
|
||||
return laddr, raddr, err
|
||||
}
|
||||
}
|
||||
return laddr, raddr, err
|
||||
}
|
||||
|
||||
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
var ret []ConnectionStat
|
||||
|
||||
args := []string{"-na"}
|
||||
switch strings.ToLower(kind) {
|
||||
default:
|
||||
fallthrough
|
||||
case "", "all", "inet":
|
||||
// nothing to add
|
||||
case "inet4":
|
||||
args = append(args, "-finet")
|
||||
case "inet6":
|
||||
args = append(args, "-finet6")
|
||||
case "tcp":
|
||||
args = append(args, "-ptcp")
|
||||
case "tcp4":
|
||||
args = append(args, "-ptcp", "-finet")
|
||||
case "tcp6":
|
||||
args = append(args, "-ptcp", "-finet6")
|
||||
case "udp":
|
||||
args = append(args, "-pudp")
|
||||
case "udp4":
|
||||
args = append(args, "-pudp", "-finet")
|
||||
case "udp6":
|
||||
args = append(args, "-pudp", "-finet6")
|
||||
case "unix":
|
||||
return ret, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
netstat, err := exec.LookPath("netstat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := invoke.CommandWithContext(ctx, netstat, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
if !strings.HasPrefix(line, "tcp") && !strings.HasPrefix(line, "udp") {
|
||||
continue
|
||||
}
|
||||
n, err := parseNetstatLine(line)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, n)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func ConnectionsPidWithContext(_ context.Context, _ string, _ int32) ([]ConnectionStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithContext(_ context.Context, _ string, _ int) ([]ConnectionStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithContext(_ context.Context, _ string, _ int32, _ int) ([]ConnectionStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, maxConn int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, maxConn)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, maxConn int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, maxConn)
|
||||
}
|
||||
|
||||
func connectionsPidMaxWithoutUidsWithContext(_ context.Context, _ string, _ int32, _ int) ([]ConnectionStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
64
vendor/github.com/shirou/gopsutil/v4/process/process_darwin.go
generated
vendored
64
vendor/github.com/shirou/gopsutil/v4/process/process_darwin.go
generated
vendored
@@ -375,29 +375,49 @@ func (p *Process) cmdlineSlice() ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The first bytes hold the nargs int, skip it.
|
||||
args := bytes.Split((pargs)[unsafe.Sizeof(int(0)):], []byte{0})
|
||||
var argStr string
|
||||
// The first element is the actual binary/command path.
|
||||
// command := args[0]
|
||||
var argSlice []string
|
||||
// var envSlice []string
|
||||
// All other, non-zero elements are arguments. The first "nargs" elements
|
||||
// are the arguments. Everything else in the slice is then the environment
|
||||
// of the process.
|
||||
for _, arg := range args[1:] {
|
||||
argStr = string(arg)
|
||||
if argStr != "" {
|
||||
if nargs > 0 {
|
||||
argSlice = append(argSlice, argStr)
|
||||
nargs--
|
||||
continue
|
||||
}
|
||||
break
|
||||
// envSlice = append(envSlice, argStr)
|
||||
}
|
||||
// procArgs reads nargs as a 4-byte uint32; skip exactly those 4 bytes
|
||||
// (matches Apple's ps using sizeof(nargs)). The previous code used
|
||||
// unsafe.Sizeof(int(0)) which is 8 on 64-bit and would discard the
|
||||
// first 4 bytes of exec_path — harmless only because chunks[0] is
|
||||
// dropped, but logically wrong.
|
||||
return parseCmdline(pargs[4:], nargs), nil
|
||||
}
|
||||
|
||||
// parseCmdline extracts argv from the kern.procargs2 buffer with the leading
|
||||
// nargs int already stripped. Layout:
|
||||
//
|
||||
// exec_path \0 [padding \0...] argv[0] \0 ... argv[nargs-1] \0 envp[0] \0 ...
|
||||
//
|
||||
// Empty argv elements within the nargs count are preserved — skipping them
|
||||
// would advance past argv[nargs-1] into envp, leaking environment values
|
||||
// (potentially secrets) into Cmdline output.
|
||||
//
|
||||
// Known limitation: a process whose argv[0] is itself an empty string is
|
||||
// indistinguishable from padding by this parser, since XNU does not expose
|
||||
// the exec/argv alignment boundary. Such a process will still see one envp
|
||||
// entry leak. Fixing it requires libgetargv-style alignment math against
|
||||
// the XNU exec layout, which is out of scope for this change.
|
||||
func parseCmdline(args []byte, nargs int) []string {
|
||||
chunks := bytes.Split(args, []byte{0})
|
||||
if len(chunks) <= 1 {
|
||||
return nil
|
||||
}
|
||||
return argSlice, err
|
||||
// Skip exec_path (chunks[0]) and any padding NULs before argv[0].
|
||||
i := 1
|
||||
for ; i < len(chunks) && len(chunks[i]) == 0; i++ {
|
||||
}
|
||||
if nargs > len(chunks)-i {
|
||||
nargs = len(chunks) - i
|
||||
}
|
||||
if nargs < 0 {
|
||||
nargs = 0
|
||||
}
|
||||
argSlice := make([]string, 0, nargs)
|
||||
for ; nargs > 0; nargs-- {
|
||||
argSlice = append(argSlice, string(chunks[i]))
|
||||
i++
|
||||
}
|
||||
return argSlice
|
||||
}
|
||||
|
||||
// cmdNameWithContext returns the command name (including spaces) without any arguments
|
||||
|
||||
20
vendor/github.com/shirou/gopsutil/v4/process/process_linux.go
generated
vendored
20
vendor/github.com/shirou/gopsutil/v4/process/process_linux.go
generated
vendored
@@ -417,8 +417,7 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M
|
||||
if len(field) < 2 {
|
||||
continue
|
||||
}
|
||||
v := strings.Trim(field[1], "kB") // remove last "kB"
|
||||
v = strings.TrimSpace(v)
|
||||
v := strings.TrimSpace(strings.TrimSuffix(field[1], " kB"))
|
||||
t, err := strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return m, err
|
||||
@@ -924,49 +923,49 @@ func (p *Process) fillFromStatusWithContext(ctx context.Context) error {
|
||||
}
|
||||
p.numCtxSwitches.Involuntary = v
|
||||
case "VmRSS":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.memInfo.RSS = v * 1024
|
||||
case "VmSize":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.memInfo.VMS = v * 1024
|
||||
case "VmSwap":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.memInfo.Swap = v * 1024
|
||||
case "VmHWM":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.memInfo.HWM = v * 1024
|
||||
case "VmData":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.memInfo.Data = v * 1024
|
||||
case "VmStk":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.memInfo.Stack = v * 1024
|
||||
case "VmLck":
|
||||
value = strings.Trim(value, " kB") // remove last "kB"
|
||||
value = strings.TrimSpace(strings.TrimSuffix(value, " kB"))
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1046,6 +1045,9 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
|
||||
}
|
||||
// Indexing from one, as described in `man proc` about the file /proc/[pid]/stat
|
||||
fields := splitProcStat(contents)
|
||||
if len(fields) < 23 {
|
||||
return 0, 0, nil, 0, 0, 0, nil, fmt.Errorf("malformed stat file: expected at least 23 fields, got %d", len(fields))
|
||||
}
|
||||
|
||||
terminal, err := strconv.ParseUint(fields[7], 10, 64)
|
||||
if err != nil {
|
||||
|
||||
49
vendor/github.com/shirou/gopsutil/v4/process/process_windows.go
generated
vendored
49
vendor/github.com/shirou/gopsutil/v4/process/process_windows.go
generated
vendored
@@ -324,6 +324,9 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
if p.Pid == 0 {
|
||||
return "System Idle Process", nil
|
||||
}
|
||||
if p.name != "" {
|
||||
return p.name, nil
|
||||
}
|
||||
if p.Pid == 4 {
|
||||
return "System", nil
|
||||
}
|
||||
@@ -333,7 +336,9 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
return "", fmt.Errorf("could not get Name: %w", err)
|
||||
}
|
||||
|
||||
return filepath.Base(exe), nil
|
||||
name := filepath.Base(exe)
|
||||
p.name = name
|
||||
return name, nil
|
||||
}
|
||||
|
||||
func (*Process) TgidWithContext(_ context.Context) (int32, error) {
|
||||
@@ -598,6 +603,8 @@ func (p *Process) NumThreadsWithContext(_ context.Context) (int32, error) {
|
||||
p.setPpid(ppid)
|
||||
}
|
||||
|
||||
p.numThreads = ret
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -900,6 +907,32 @@ func getFromSnapProcess(pid int32) (int32, int32, string, error) { //nolint:unpa
|
||||
return 0, 0, "", fmt.Errorf("couldn't find pid: %d", pid)
|
||||
}
|
||||
|
||||
func buildSnapProcessMap() (map[uint32]windows.ProcessEntry32, error) {
|
||||
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer windows.CloseHandle(snap)
|
||||
|
||||
var pe32 windows.ProcessEntry32
|
||||
pe32.Size = uint32(unsafe.Sizeof(pe32))
|
||||
if err := windows.Process32First(snap, &pe32); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snapMap := make(map[uint32]windows.ProcessEntry32)
|
||||
for {
|
||||
snapMap[pe32.ProcessID] = pe32
|
||||
if err := windows.Process32Next(snap, &pe32); err != nil {
|
||||
if errors.Is(err, windows.ERROR_NO_MORE_FILES) {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return snapMap, nil
|
||||
}
|
||||
|
||||
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
||||
out := []*Process{}
|
||||
|
||||
@@ -908,11 +941,25 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
||||
return out, fmt.Errorf("could not get Processes %w", err)
|
||||
}
|
||||
|
||||
// Note: The PID enumeration and snapshot creation are separate calls
|
||||
// and may not be perfectly consistent due to timing.
|
||||
snapMap, err := buildSnapProcessMap()
|
||||
if err != nil {
|
||||
return out, fmt.Errorf("could not build process snapshot: %w", err)
|
||||
}
|
||||
|
||||
for _, pid := range pids {
|
||||
p, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if entry, ok := snapMap[uint32(pid)]; ok {
|
||||
p.name = windows.UTF16ToString(entry.ExeFile[:])
|
||||
p.setPpid(int32(entry.ParentProcessID))
|
||||
p.numThreads = int32(entry.Threads)
|
||||
}
|
||||
|
||||
out = append(out, p)
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/testcontainers/testcontainers-go/Pipfile
generated
vendored
2
vendor/github.com/testcontainers/testcontainers-go/Pipfile
generated
vendored
@@ -8,7 +8,7 @@ verify_ssl = true
|
||||
[packages]
|
||||
mkdocs = "==1.5.3"
|
||||
mkdocs-codeinclude-plugin = "==0.3.1"
|
||||
mkdocs-include-markdown-plugin = "==7.2.2"
|
||||
mkdocs-include-markdown-plugin = "==7.3.0"
|
||||
mkdocs-material = "==9.5.18"
|
||||
mkdocs-markdownextradata-plugin = "==0.2.6"
|
||||
|
||||
|
||||
48
vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock
generated
vendored
48
vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock
generated
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "d2dc50d3b1c6818dd8a8fb4fa7a60013292b7f173db53d3e996bf43b4191ad70"
|
||||
"sha256": "9836de74487210f57ac1040d06b403490e5171be35a8b5816a5361b4a2d02e01"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -177,11 +177,11 @@
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a",
|
||||
"sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"
|
||||
"sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2",
|
||||
"sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==8.3.1"
|
||||
"version": "==8.4.1"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
@@ -200,11 +200,12 @@
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea",
|
||||
"sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"
|
||||
"sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8",
|
||||
"sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==3.11"
|
||||
"version": "==3.15"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
@@ -353,12 +354,12 @@
|
||||
},
|
||||
"mkdocs-include-markdown-plugin": {
|
||||
"hashes": [
|
||||
"sha256:f052ccb741eccf498116b826c1d78a2d761c56747372594709441cee0963fbc9",
|
||||
"sha256:f2ec4487cf32d3e33ca528f9366f20fb9280ded9c8d1630eb2bbda244962dcd1"
|
||||
"sha256:2800126746452e31c2e321bbd43c8190b356e0de353e20cbc16a34a3c3d6796c",
|
||||
"sha256:5b5c99b5d3c9b9ce0114a9e60353bbafb6be53a26c2d3b74ec6b767a7a8e55ca"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==7.2.2"
|
||||
"version": "==7.3.0"
|
||||
},
|
||||
"mkdocs-markdownextradata-plugin": {
|
||||
"hashes": [
|
||||
@@ -388,11 +389,11 @@
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4",
|
||||
"sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"
|
||||
"sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e",
|
||||
"sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==26.0"
|
||||
"version": "==26.2"
|
||||
},
|
||||
"paginate": {
|
||||
"hashes": [
|
||||
@@ -402,19 +403,19 @@
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645",
|
||||
"sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"
|
||||
"sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a",
|
||||
"sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==1.0.4"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"platformdirs": {
|
||||
"hashes": [
|
||||
"sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934",
|
||||
"sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868"
|
||||
"sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7",
|
||||
"sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==4.9.4"
|
||||
"version": "==4.10.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
@@ -641,11 +642,12 @@
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed",
|
||||
"sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"
|
||||
"sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c",
|
||||
"sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==2.6.3"
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==2.7.0"
|
||||
},
|
||||
"watchdog": {
|
||||
"hashes": [
|
||||
|
||||
2
vendor/github.com/testcontainers/testcontainers-go/commons-test.mk
generated
vendored
2
vendor/github.com/testcontainers/testcontainers-go/commons-test.mk
generated
vendored
@@ -15,7 +15,7 @@ $(GOBIN)/mockery:
|
||||
$(call go_install,github.com/vektra/mockery/v2@v2.53.4)
|
||||
|
||||
$(GOBIN)/gci:
|
||||
$(call go_install,github.com/daixiang0/gci@v0.13.5)
|
||||
$(call go_install,github.com/daixiang0/gci@v0.14.0)
|
||||
|
||||
.PHONY: install
|
||||
install: $(GOBIN)/golangci-lint $(GOBIN)/gotestsum $(GOBIN)/mockery
|
||||
|
||||
62
vendor/github.com/testcontainers/testcontainers-go/docker.go
generated
vendored
62
vendor/github.com/testcontainers/testcontainers-go/docker.go
generated
vendored
@@ -87,6 +87,8 @@ type DockerContainer struct {
|
||||
// logProductionCancel is used to signal the log production to stop.
|
||||
logProductionCancel context.CancelCauseFunc
|
||||
logProductionCtx context.Context
|
||||
// logProductionDone is closed when the log production goroutine exits.
|
||||
logProductionDone chan struct{}
|
||||
|
||||
logProductionTimeout *time.Duration
|
||||
logger log.Logger
|
||||
@@ -813,16 +815,19 @@ func (c *DockerContainer) startLogProduction(ctx context.Context, opts ...LogPro
|
||||
|
||||
// Setup the log production context which will be used to stop the log production.
|
||||
c.logProductionCtx, c.logProductionCancel = context.WithCancelCause(ctx)
|
||||
c.logProductionDone = make(chan struct{})
|
||||
|
||||
// We capture context cancel function to avoid data race with multiple
|
||||
// calls to startLogProduction.
|
||||
go func(cancel context.CancelCauseFunc) {
|
||||
go func(cancel context.CancelCauseFunc, done chan struct{}) {
|
||||
// Ensure the context is cancelled when log productions completes
|
||||
// so that GetLogProductionErrorChannel functions correctly.
|
||||
defer cancel(nil)
|
||||
// Signal that the goroutine has exited so stopLogProduction can drain.
|
||||
defer close(done)
|
||||
|
||||
c.logProducer(stdout, stderr)
|
||||
}(c.logProductionCancel)
|
||||
}(c.logProductionCancel, c.logProductionDone)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -903,9 +908,38 @@ func (c *DockerContainer) stopLogProduction() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Signal the log production to stop.
|
||||
// Wait for the log production goroutine to finish draining any buffered
|
||||
// logs before cancelling. When the container has already exited, the
|
||||
// goroutine will reach EOF naturally and close logProductionDone on its
|
||||
// own. The bounded timeout prevents blocking indefinitely when the
|
||||
// container is still actively streaming (e.g. Stop() called on a running
|
||||
// container).
|
||||
if c.logProductionDone != nil {
|
||||
select {
|
||||
case <-c.logProductionDone:
|
||||
// Goroutine already finished naturally; nothing more to do.
|
||||
return nil
|
||||
case <-time.After(minLogProductionTimeout):
|
||||
// Timed out waiting for natural exit; force-cancel now.
|
||||
}
|
||||
}
|
||||
|
||||
// Signal the log production to stop (for still-running containers).
|
||||
c.logProductionCancel(errLogProductionStop)
|
||||
|
||||
// Wait for the goroutine to acknowledge the cancellation. Context
|
||||
// cancellation propagates into the Docker transport and should unblock
|
||||
// stdcopy.StdCopy promptly, but we bound the wait to match
|
||||
// minLogProductionTimeout to guard against stuck kernel socket reads or
|
||||
// daemon transport failures that might not honour context cancellation.
|
||||
if c.logProductionDone != nil {
|
||||
select {
|
||||
case <-c.logProductionDone:
|
||||
case <-time.After(minLogProductionTimeout):
|
||||
c.logger.Printf("timeout waiting for log production goroutine to exit; a goroutine may have leaked")
|
||||
}
|
||||
}
|
||||
|
||||
if err := context.Cause(c.logProductionCtx); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, errLogProductionStop):
|
||||
@@ -1861,6 +1895,7 @@ func (p *DockerProvider) SaveImagesWithOpts(ctx context.Context, output string,
|
||||
func SaveDockerImageWithPlatforms(platforms ...specs.Platform) SaveImageOption {
|
||||
return func(opts *saveImageOptions) error {
|
||||
opts.dockerSaveOpts = append(opts.dockerSaveOpts, client.ImageSaveWithPlatforms(platforms...))
|
||||
opts.platforms = append(opts.platforms, platforms...)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1871,6 +1906,27 @@ func (p *DockerProvider) PullImage(ctx context.Context, img string) error {
|
||||
return p.attemptToPullImage(ctx, img, client.ImagePullOptions{})
|
||||
}
|
||||
|
||||
// PullImageWithOpts pulls image from registry, passing options to the provider.
|
||||
func (p *DockerProvider) PullImageWithOpts(ctx context.Context, img string, opts ...PullImageOption) error {
|
||||
pullOpts := pullImageOptions{}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(&pullOpts); err != nil {
|
||||
return fmt.Errorf("applying pull image option: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return p.attemptToPullImage(ctx, img, pullOpts.dockerPullOpts)
|
||||
}
|
||||
|
||||
func PullDockerImageWithPlatform(platform specs.Platform) PullImageOption {
|
||||
return func(opts *pullImageOptions) error {
|
||||
opts.dockerPullOpts.Platforms = append(opts.dockerPullOpts.Platforms, platform)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var permanentClientErrors = []func(error) bool{
|
||||
errdefs.IsNotFound,
|
||||
errdefs.IsInvalidArgument,
|
||||
|
||||
9
vendor/github.com/testcontainers/testcontainers-go/generic.go
generated
vendored
9
vendor/github.com/testcontainers/testcontainers-go/generic.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/testcontainers/testcontainers-go/internal/core"
|
||||
@@ -78,14 +77,6 @@ func GenericContainer(ctx context.Context, req GenericContainerRequest) (Contain
|
||||
}
|
||||
if err != nil {
|
||||
// At this point `c` might not be nil. Give the caller an opportunity to call Destroy on the container.
|
||||
// TODO: Remove this debugging.
|
||||
if strings.Contains(err.Error(), "toomanyrequests") {
|
||||
// Debugging information for rate limiting.
|
||||
cfg, err := getDockerConfig()
|
||||
if err == nil {
|
||||
fmt.Printf("XXX: too many requests: %+v", cfg)
|
||||
}
|
||||
}
|
||||
return c, fmt.Errorf("create container: %w", err)
|
||||
}
|
||||
|
||||
|
||||
31
vendor/github.com/testcontainers/testcontainers-go/image.go
generated
vendored
31
vendor/github.com/testcontainers/testcontainers-go/image.go
generated
vendored
@@ -2,8 +2,10 @@ package testcontainers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/moby/moby/client"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ImageInfo represents summary information of an image
|
||||
@@ -14,14 +16,43 @@ type ImageInfo struct {
|
||||
|
||||
type saveImageOptions struct {
|
||||
dockerSaveOpts []client.ImageSaveOption
|
||||
platforms []specs.Platform
|
||||
}
|
||||
|
||||
type SaveImageOption func(*saveImageOptions) error
|
||||
|
||||
type pullImageOptions struct {
|
||||
dockerPullOpts client.ImagePullOptions
|
||||
}
|
||||
|
||||
type PullImageOption func(*pullImageOptions) error
|
||||
|
||||
// ResolveSaveImageOptions applies save image options and returns the platform to
|
||||
// use for a coordinated containerd import, if exactly one platform was requested.
|
||||
func ResolveSaveImageOptions(opts ...SaveImageOption) (*specs.Platform, error) {
|
||||
saveOpts := saveImageOptions{}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(&saveOpts); err != nil {
|
||||
return nil, fmt.Errorf("applying save image option: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(saveOpts.platforms) {
|
||||
case 0:
|
||||
return nil, nil
|
||||
case 1:
|
||||
return &saveOpts.platforms[0], nil
|
||||
default:
|
||||
return nil, fmt.Errorf("at most one platform is supported, got %d", len(saveOpts.platforms))
|
||||
}
|
||||
}
|
||||
|
||||
// ImageProvider allows manipulating images
|
||||
type ImageProvider interface {
|
||||
ListImages(context.Context) ([]ImageInfo, error)
|
||||
SaveImages(context.Context, string, ...string) error
|
||||
SaveImagesWithOpts(context.Context, string, []string, ...SaveImageOption) error
|
||||
PullImage(context.Context, string) error
|
||||
PullImageWithOpts(context.Context, string, ...PullImageOption) error
|
||||
}
|
||||
|
||||
2
vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go
generated
vendored
2
vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go
generated
vendored
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/magiconair/properties"
|
||||
)
|
||||
|
||||
const ReaperDefaultImage = "testcontainers/ryuk:0.13.0"
|
||||
const ReaperDefaultImage = "testcontainers/ryuk:0.14.0"
|
||||
|
||||
var (
|
||||
tcConfig Config
|
||||
|
||||
2
vendor/github.com/testcontainers/testcontainers-go/internal/version.go
generated
vendored
2
vendor/github.com/testcontainers/testcontainers-go/internal/version.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
package internal
|
||||
|
||||
// Version is the next development version of the application
|
||||
const Version = "0.42.0"
|
||||
const Version = "0.43.0"
|
||||
|
||||
6
vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml
generated
vendored
6
vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml
generated
vendored
@@ -55,10 +55,11 @@ nav:
|
||||
- HostPort: features/wait/host_port.md
|
||||
- HTTP: features/wait/http.md
|
||||
- Log: features/wait/log.md
|
||||
- Multi: features/wait/multi.md
|
||||
- SQL: features/wait/sql.md
|
||||
- TLS: features/wait/tls.md
|
||||
- Walk: features/wait/walk.md
|
||||
- All: features/wait/all.md
|
||||
- Any: features/wait/any.md
|
||||
- features/files_and_mounts.md
|
||||
- features/follow_logs.md
|
||||
- features/garbage_collector.md
|
||||
@@ -85,6 +86,7 @@ nav:
|
||||
- modules/consul.md
|
||||
- modules/couchbase.md
|
||||
- modules/databend.md
|
||||
- modules/dex.md
|
||||
- modules/dind.md
|
||||
- modules/dockermcpgateway.md
|
||||
- modules/dockermodelrunner.md
|
||||
@@ -162,4 +164,4 @@ nav:
|
||||
- Getting help: getting_help.md
|
||||
edit_uri: edit/main/docs/
|
||||
extra:
|
||||
latest_version: v0.42.0
|
||||
latest_version: v0.43.0
|
||||
|
||||
2
vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go
generated
vendored
2
vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go
generated
vendored
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
const (
|
||||
// hubSshdImage {
|
||||
sshdImage string = "testcontainers/sshd:1.3.0"
|
||||
sshdImage string = "testcontainers/sshd:1.4.0"
|
||||
// }
|
||||
|
||||
// HostInternal is the internal hostname used to reach the host from the container,
|
||||
|
||||
16
vendor/github.com/testcontainers/testcontainers-go/reaper.go
generated
vendored
16
vendor/github.com/testcontainers/testcontainers-go/reaper.go
generated
vendored
@@ -367,6 +367,20 @@ func (r *reaperSpawner) fromContainer(ctx context.Context, sessionID string, pro
|
||||
}, nil
|
||||
}
|
||||
|
||||
// defaultRyukWaitStrategy returns the wait strategy used when creating a new
|
||||
// reaper container. It combines a log match for "Started" (the moment ryuk's
|
||||
// TCP listener is bound inside the container, which is the readiness signal
|
||||
// also used by other Testcontainers libraries) with a host port-mapping check,
|
||||
// to guard against the docker-proxy accepting TCP connections before the ryuk
|
||||
// process is actually listening — a race that surfaced once the ryuk binary
|
||||
// was UPX-compressed.
|
||||
func defaultRyukWaitStrategy(port string) wait.Strategy {
|
||||
return wait.ForAll(
|
||||
wait.ForLog("Started"),
|
||||
wait.ForListeningPort(port),
|
||||
)
|
||||
}
|
||||
|
||||
// newReaper creates a connected Reaper with a sessionID to identify containers
|
||||
// and a provider to use.
|
||||
func (r *reaperSpawner) newReaper(ctx context.Context, sessionID string, provider ReaperProvider) (reaper *Reaper, err error) {
|
||||
@@ -378,7 +392,7 @@ func (r *reaperSpawner) newReaper(ctx context.Context, sessionID string, provide
|
||||
Image: config.ReaperDefaultImage,
|
||||
ExposedPorts: []string{port.String()},
|
||||
Labels: core.DefaultLabels(sessionID),
|
||||
WaitingFor: wait.ForListeningPort(port.String()),
|
||||
WaitingFor: defaultRyukWaitStrategy(port.String()),
|
||||
Name: reaperContainerNameFromSessionID(sessionID),
|
||||
HostConfigModifier: func(hc *container.HostConfig) {
|
||||
hc.AutoRemove = true
|
||||
|
||||
2
vendor/github.com/testcontainers/testcontainers-go/requirements.txt
generated
vendored
2
vendor/github.com/testcontainers/testcontainers-go/requirements.txt
generated
vendored
@@ -1,5 +1,5 @@
|
||||
mkdocs==1.5.3
|
||||
mkdocs-codeinclude-plugin==0.3.1
|
||||
mkdocs-include-markdown-plugin==7.2.1
|
||||
mkdocs-include-markdown-plugin==7.2.2
|
||||
mkdocs-material==9.5.18
|
||||
mkdocs-markdownextradata-plugin==0.2.6
|
||||
|
||||
128
vendor/github.com/testcontainers/testcontainers-go/wait/any.go
generated
vendored
Normal file
128
vendor/github.com/testcontainers/testcontainers-go/wait/any.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Implement interface
|
||||
var (
|
||||
_ Strategy = (*AnyMultiStrategy)(nil)
|
||||
_ StrategyTimeout = (*AnyMultiStrategy)(nil)
|
||||
)
|
||||
|
||||
type AnyMultiStrategy struct {
|
||||
// all Strategies should have a startupTimeout to avoid waiting infinitely
|
||||
timeout *time.Duration
|
||||
deadline *time.Duration
|
||||
|
||||
// additional properties
|
||||
Strategies []Strategy
|
||||
}
|
||||
|
||||
// WithStartupTimeoutDefault sets the default timeout for all inner wait strategies.
|
||||
func (ms *AnyMultiStrategy) WithStartupTimeoutDefault(timeout time.Duration) *AnyMultiStrategy {
|
||||
ms.timeout = &timeout
|
||||
return ms
|
||||
}
|
||||
|
||||
// WithDeadline sets a time.Duration which limits all wait strategies.
|
||||
func (ms *AnyMultiStrategy) WithDeadline(deadline time.Duration) *AnyMultiStrategy {
|
||||
ms.deadline = &deadline
|
||||
return ms
|
||||
}
|
||||
|
||||
// ForAny returns a WaitStrategy that waits for any of the supplied conditions
|
||||
// to become true (after which it cancels the remaining ones).
|
||||
//
|
||||
// Failures are not permitted: any strategy which fails will have its error
|
||||
// immediately returned.
|
||||
func ForAny(strategies ...Strategy) *AnyMultiStrategy {
|
||||
return &AnyMultiStrategy{
|
||||
Strategies: strategies,
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *AnyMultiStrategy) Timeout() *time.Duration {
|
||||
return ms.timeout
|
||||
}
|
||||
|
||||
// String returns a human-readable description of the wait strategy.
|
||||
func (ms *AnyMultiStrategy) String() string {
|
||||
if len(ms.Strategies) == 0 {
|
||||
return "any of: (none)"
|
||||
}
|
||||
|
||||
var strategies []string
|
||||
for _, strategy := range ms.Strategies {
|
||||
if strategy == nil || reflect.ValueOf(strategy).IsNil() {
|
||||
continue
|
||||
}
|
||||
if s, ok := strategy.(fmt.Stringer); ok {
|
||||
strategies = append(strategies, s.String())
|
||||
} else {
|
||||
strategies = append(strategies, fmt.Sprintf("%T", strategy))
|
||||
}
|
||||
}
|
||||
|
||||
// Always include "any of:" prefix to make it clear this is a AnyMultiStrategy
|
||||
// even when there's only one strategy after filtering out nils.
|
||||
return "any of: [" + strings.Join(strategies, ", ") + "]"
|
||||
}
|
||||
|
||||
func (ms *AnyMultiStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) error {
|
||||
if len(ms.Strategies) == 0 {
|
||||
return errors.New("no wait strategy supplied")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel() // All remaining strategies will stop when this fires.
|
||||
|
||||
if ms.deadline != nil {
|
||||
ctx, cancel = context.WithTimeout(ctx, *ms.deadline)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
resCh := make(chan error, len(ms.Strategies))
|
||||
var valid int
|
||||
|
||||
for _, strategy := range ms.Strategies {
|
||||
if strategy == nil || reflect.ValueOf(strategy).IsNil() {
|
||||
// A module could be appending strategies after part of the container initialization,
|
||||
// and use wait.ForAny on a not initialized strategy.
|
||||
// In this case, we just skip the nil strategy.
|
||||
continue
|
||||
}
|
||||
valid++
|
||||
|
||||
strategyCtx := ctx
|
||||
// Set default Timeout when strategy implements StrategyTimeout
|
||||
if st, ok := strategy.(StrategyTimeout); ok {
|
||||
if ms.Timeout() != nil && st.Timeout() == nil {
|
||||
strategyCtx, cancel = context.WithTimeout(ctx, *ms.Timeout())
|
||||
defer cancel()
|
||||
}
|
||||
}
|
||||
go func() { resCh <- strategy.WaitUntilReady(strategyCtx, target) }()
|
||||
}
|
||||
|
||||
if valid == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case err := <-resCh:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("timed out waiting for strategies: %w", ctx.Err())
|
||||
}
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/testcontainers/testcontainers-go/wait/sql.go
generated
vendored
6
vendor/github.com/testcontainers/testcontainers-go/wait/sql.go
generated
vendored
@@ -17,7 +17,7 @@ var (
|
||||
const defaultForSQLQuery = "SELECT 1"
|
||||
|
||||
// ForSQL constructs a new waitForSql strategy for the given driver
|
||||
func ForSQL(port string, driver string, url func(host string, port string) string) *waitForSQL {
|
||||
func ForSQL(port string, driver string, url func(host string, port network.Port) string) *waitForSQL {
|
||||
return &waitForSQL{
|
||||
Port: port,
|
||||
URL: url,
|
||||
@@ -31,7 +31,7 @@ func ForSQL(port string, driver string, url func(host string, port string) strin
|
||||
type waitForSQL struct {
|
||||
timeout *time.Duration
|
||||
|
||||
URL func(host string, port string) string
|
||||
URL func(host string, port network.Port) string
|
||||
Driver string
|
||||
Port string
|
||||
startupTimeout time.Duration
|
||||
@@ -114,7 +114,7 @@ func (w *waitForSQL) WaitUntilReady(ctx context.Context, target StrategyTarget)
|
||||
}
|
||||
}
|
||||
|
||||
db, err := sql.Open(w.Driver, w.URL(host, port.String()))
|
||||
db, err := sql.Open(w.Driver, w.URL(host, port))
|
||||
if err != nil {
|
||||
return fmt.Errorf("sql.Open: %w", err)
|
||||
}
|
||||
|
||||
40
vendor/github.com/testcontainers/testcontainers-go/wait/walk.go
generated
vendored
40
vendor/github.com/testcontainers/testcontainers-go/wait/walk.go
generated
vendored
@@ -59,23 +59,33 @@ func walk(root *Strategy, visit VisitFunc) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if s, ok := (*root).(*MultiStrategy); ok {
|
||||
var i int
|
||||
for range s.Strategies {
|
||||
if err := walk(&s.Strategies[i], visit); err != nil {
|
||||
if errors.Is(err, ErrVisitRemove) {
|
||||
s.Strategies = slices.Delete(s.Strategies, i, i+1)
|
||||
if errors.Is(err, VisitStop) {
|
||||
return VisitStop
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
i++
|
||||
switch s := (*root).(type) {
|
||||
case *MultiStrategy:
|
||||
if err := walkAndMutate(&s.Strategies, visit); err != nil {
|
||||
return err
|
||||
}
|
||||
case *AnyMultiStrategy:
|
||||
if err := walkAndMutate(&s.Strategies, visit); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func walkAndMutate(strategies *[]Strategy, visit VisitFunc) error {
|
||||
for i := 0; i < len(*strategies); {
|
||||
if err := walk(&(*strategies)[i], visit); err != nil {
|
||||
if errors.Is(err, ErrVisitRemove) {
|
||||
*strategies = slices.Delete(*strategies, i, i+1)
|
||||
if errors.Is(err, VisitStop) {
|
||||
return VisitStop
|
||||
}
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
i++
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
@@ -1086,7 +1086,7 @@ github.com/moby/docker-image-spec/specs-go/v1
|
||||
github.com/moby/go-archive
|
||||
github.com/moby/go-archive/compression
|
||||
github.com/moby/go-archive/tarheader
|
||||
# github.com/moby/moby/api v1.54.1
|
||||
# github.com/moby/moby/api v1.54.2
|
||||
## explicit; go 1.24
|
||||
github.com/moby/moby/api/pkg/authconfig
|
||||
github.com/moby/moby/api/pkg/stdcopy
|
||||
@@ -1995,7 +1995,7 @@ github.com/shamaton/msgpack/v2/internal/encoding
|
||||
github.com/shamaton/msgpack/v2/internal/stream/decoding
|
||||
github.com/shamaton/msgpack/v2/internal/stream/encoding
|
||||
github.com/shamaton/msgpack/v2/time
|
||||
# github.com/shirou/gopsutil/v4 v4.26.3
|
||||
# github.com/shirou/gopsutil/v4 v4.26.5
|
||||
## explicit; go 1.24.0
|
||||
github.com/shirou/gopsutil/v4/common
|
||||
github.com/shirou/gopsutil/v4/cpu
|
||||
@@ -2070,7 +2070,7 @@ github.com/tchap/go-patricia/v2/patricia
|
||||
## explicit
|
||||
github.com/test-go/testify/mock
|
||||
github.com/test-go/testify/require
|
||||
# github.com/testcontainers/testcontainers-go v0.42.0
|
||||
# github.com/testcontainers/testcontainers-go v0.43.0
|
||||
## explicit; go 1.25.0
|
||||
github.com/testcontainers/testcontainers-go
|
||||
github.com/testcontainers/testcontainers-go/exec
|
||||
@@ -2080,7 +2080,7 @@ github.com/testcontainers/testcontainers-go/internal/core
|
||||
github.com/testcontainers/testcontainers-go/internal/core/network
|
||||
github.com/testcontainers/testcontainers-go/log
|
||||
github.com/testcontainers/testcontainers-go/wait
|
||||
# github.com/testcontainers/testcontainers-go/modules/opensearch v0.42.0
|
||||
# github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0
|
||||
## explicit; go 1.25.0
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch
|
||||
# github.com/theckman/yacspin v0.13.12
|
||||
|
||||
Reference in New Issue
Block a user