Skip to content

July upstream changes#195

Open
QuintenQVD0 wants to merge 13 commits into
mainfrom
07-upstream
Open

July upstream changes#195
QuintenQVD0 wants to merge 13 commits into
mainfrom
07-upstream

Conversation

@QuintenQVD0

@QuintenQVD0 QuintenQVD0 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Changes

  • All from upstream, needs testing and panel changes

Summary by CodeRabbit

  • New Features

    • Added a restore_host_allowlist setting to control which hostnames, IPs, and CIDR ranges backup restores may download from.
  • Bug Fixes

    • Hardened backup restore/download: strict UUID parsing, required/validated download URLs, stricter supported gzip Content-Type handling, and safer destination allow/deny checks.
    • Improved Docker image registry credential selection for more reliable authenticated pulls.
    • Strengthened disk-quota handling with overflow-safe accounting and corrected quota enforcement across filesystem/SFTP operations.
    • Backup and filesystem operations now validate identifiers/paths more strictly; chtimes no longer follows symlinks.
  • Behavior / Security

    • SFTP access is denied and active SFTP sessions are cancelled during protected server states (install/transfer/restore).

@QuintenQVD0 QuintenQVD0 requested a review from a team as a code owner July 4, 2026 09:18
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@QuintenQVD0, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0fbde844-a700-4d26-a36a-f78369bf9e99

📥 Commits

Reviewing files that changed from the base of the PR and between be4335f and 4da9bd3.

📒 Files selected for processing (2)
  • config/config_docker_test.go
  • router/router_server_backup_test.go
📝 Walkthrough

Walkthrough

This PR adds Docker registry credential resolution by image reference, overflow-safe disk quota accounting with a quota-aware file wrapper, protected server-state enforcement that cancels and blocks SFTP sessions, canonical UUID validation for backup identifiers, hardened backup restore download validation with a configurable host allowlist, and a symlink-safe timestamp fix.

Changes

Docker registry credential resolution

Layer / File(s) Summary
Registry reference parsing and matching
config/config_docker.go, config/onfig_docker_test.go
Adds RegistryCredentialsForImage, parseDockerRegistryReference, and registryPathMatchesImage with tests covering domain/path matching and sibling-path rejection.
Wiring into pull paths
environment/docker/container.go, server/install.go
Container image pull and installation image pull use the new credential resolver instead of manual prefix matching.

Disk quota overflow safety and quota-aware writes

Layer / File(s) Summary
Overflow-safe Quota Add/CanFit
internal/ufs/fs_quota.go, internal/ufs/fs_quota_test.go
Add uses CAS retries with saturation; CanFit avoids overflow-prone addition; tests cover overflow and clamping.
Disk reservation helpers
server/filesystem/disk_space.go
Adds reserveDisk/adjustDisk with capacity checks and locking; reorders hard-link init in DirectorySize.
quotaFile wrapper and touch/compress integration
server/filesystem/quota_file.go, server/filesystem/filesystem.go, server/filesystem/compress.go, server/filesystem/filesystem_test.go
New quotaFile enforces quota during Write/WriteAt/ReadFrom/Close; Touch wraps handles with prior size; compression paths guard against negative/overflowing sizes.

Protected server state and SFTP enforcement

Layer / File(s) Summary
Protected state setters
server/install.go, server/state_test.go
SetInstalling/SetTransferring/SetRestoring cancel SFTP activity; IsInProtectedState added; install run cancels SFTP after lock acquisition.
SFTP handler enforcement
sftp/handler.go, sftp/handler_test.go
Handler.can denies permissions in protected state; new quotaWriterAt rejects writes and maps disk errors; Filewrite returns the wrapped writer.

Backup UUID validation and restore hardening

Layer / File(s) Summary
Identifier validation
server/backup/backup.go, server/backup/backup_local.go, server/backup/backup_s3.go, server/backup/backup_test.go
Path, Size, Checksum, Remove, Generate, Restore, LocateLocal validate canonical UUID identifiers before filesystem operations.
Restore endpoint hardening
router/router_server_backup.go, config/config.go, router/router_download.go
postServerRestoreBackup/deleteServerBackup/postServerBackup parse UUIDs, validate download URLs against blocked IPs and a new RestoreHostAllowlist, use a hardened HTTP client, and validate content-type; getDownloadBackup uses the canonical backup UUID lookup.
Restore endpoint tests
router/router_server_backup_test.go
Mock client/environment, test context builder, and tests for loopback/UUID/status/content-type/allowlist/timeout behavior.

Symlink-safe timestamp fix

Layer / File(s) Summary
Chtimesat symlink handling
internal/ufs/fs_unix.go, internal/ufs/fs_unix_test.go
UtimesNanoAt now passes AT_SYMLINK_NOFOLLOW; test verifies symlink target timestamps are unaffected.

Estimated code review effort: 4 (Complex) | ~75 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Router as postServerRestoreBackup
  participant Validator as validateBackupDownloadUrl
  participant HttpClient as backupRestoreHttpClient
  participant Remote as Download URL
  Client->>Router: restore request (download_url)
  Router->>Validator: validateBackupDownloadUrl(url)
  Validator->>Validator: isBlockedBackupRestoreIP / isAllowedBackupRestoreDestination
  Validator-->>Router: ok or backupDownloadError
  Router->>HttpClient: GET download_url
  HttpClient->>Remote: resolve host, dial, fetch
  Remote-->>HttpClient: response
  HttpClient-->>Router: status, content-type
  Router->>Router: isSupportedBackupRestoreContentType check
  Router-->>Client: 400 or restore proceeds
Loading
sequenceDiagram
  participant Client as SFTP Client
  participant Handler
  participant Writer as quotaWriterAt
  participant Server
  Client->>Handler: Filewrite request
  Handler->>Server: IsInProtectedState()
  Server-->>Handler: true/false
  Handler-->>Client: ErrSSHFxPermissionDenied (if protected)
  Handler->>Writer: WriteAt(data)
  Writer->>Server: IsInProtectedState()
  Writer-->>Client: denied or forwarded result
Loading

Poem

A rabbit hops through quota's maze,
Saturates at max, no overflow craze,
Backups locked with UUIDs tight,
Allowlists guard the download's flight,
SFTP hushes when servers restore —
Thump-thump! Ship it, and code some more. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is generic and only indicates the changes came from upstream, without describing the actual content of the pull request. Use a concise title that names the main change, such as backup restore hardening, quota fixes, or protected-state SFTP behavior.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 07-upstream

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
internal/ufs/fs_unix_test.go (1)

322-333: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Also assert the symlink's own mtime changed.

The test confirms the target is untouched but never verifies that link itself actually received the new changed timestamp, leaving the positive half of the AT_SYMLINK_NOFOLLOW behavior unverified.

✅ Suggested addition
 	st, err := os.Lstat(target)
 	if err != nil {
 		t.Fatal(err)
 	}
 	if !st.ModTime().Equal(original) {
 		t.Fatalf("expected target mtime to remain %s, got %s", original, st.ModTime())
 	}
+
+	linkStat, err := os.Lstat(filepath.Join(root, "link"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !linkStat.ModTime().Equal(changed) {
+		t.Fatalf("expected link mtime to be %s, got %s", changed, linkStat.ModTime())
+	}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/ufs/fs_unix_test.go` around lines 322 - 333, The symlink timestamp
test in the `fs.Chtimes` path only verifies that the target file’s mtime stays
unchanged, but it never checks that the symlink itself was updated. After
calling `fs.Chtimes("link", changed, changed)`, add an assertion using
`os.Lstat("link")` to confirm the link’s own `ModTime()` matches `changed`,
alongside the existing target check, so the `AT_SYMLINK_NOFOLLOW` behavior is
fully covered.
router/router_server_backup.go (1)

249-256: 📐 Maintainability & Code Quality | 🔵 Trivial

Duplicate UUID canonicalization logic with backup.go's normalizedIdentifier.

parseBackupUuid re-implements the identical parse/length/lowercase-match check found in server/backup/backup.go. Consider consolidating into one exported helper to avoid drift between the two validation paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@router/router_server_backup.go` around lines 249 - 256, The UUID
canonicalization check in parseBackupUuid duplicates the same
parse/length/lowercase validation already used by normalizedIdentifier in
backup.go. Refactor parseBackupUuid to call a shared helper (ideally the
existing normalizedIdentifier or a common exported utility) so both validation
paths stay identical, while keeping the current AbortWithStatusJSON behavior on
failure.
server/backup/backup.go (2)

101-133: 📐 Maintainability & Code Quality | 🔵 Trivial

LGTM on identifier validation, but logic is duplicated with the router layer.

normalizedIdentifier()'s canonical-UUID check (parse + length + lowercase match) duplicates the identical logic in router/router_server_backup.go's parseBackupUuid. Consider extracting a single shared helper (e.g., in a small uuidutil package or exported from backup) that both call, so future changes to canonicalization rules don't need to be kept in sync in two places.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/backup/backup.go` around lines 101 - 133, The canonical backup UUID
validation logic is duplicated between Backup.normalizedIdentifier() and
router/router_server_backup.go’s parseBackupUuid, so extract the
parse-plus-canonicalization check into one shared helper and have both call it.
Keep the existing behavior the same, but move the UUID parsing/length/lowercase
validation into a single reusable function (for example in backup or a small
uuidutil helper) so future canonicalization changes only need to be made in one
place.

144-146: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

LGTM on the added validation.

Unrelated to this diff: static analysis flags the pre-existing sha1.New() call a few lines below as a broken hash algorithm. Since this checksum is only used for backup integrity/dedup rather than a cryptographic security guarantee, and changing it would require coordinated panel-side changes, this is optional and out of scope for this PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/backup/backup.go` around lines 144 - 146, The new validateIdentifier
addition is fine, but the backup checksum code still uses sha1.New(), which
static analysis flags as a broken hash algorithm. If you choose to address it in
this area, update the checksum path in backup/backup.go to use a non-broken hash
implementation and keep the change coordinated with any panel-side checksum
consumers, since the checksum is used for backup integrity/dedup and must remain
compatible.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@environment/docker/container.go`:
- Line 393: The build is failing because ensureImageExists references an
undefined img variable; update the Docker registry credential lookup to use the
existing image parameter instead. Fix the assignment in ensureImageExists so
config.Get().Docker.RegistryCredentialsForImage is called with image, keeping
the surrounding registry and registryAuth handling unchanged.

In `@router/router_server_backup.go`:
- Around line 222-227: The deleteServerBackup handler is missing the server UUID
required by backup.LocateLocal. Update the deleteServerBackup flow to bind the
server from middleware.ExtractServer(c) and pass s.ID() as the third argument
when calling backup.LocateLocal, alongside the existing
middleware.ExtractApiClient(c) and backupUuid values.
- Around line 107-120: The backup lookup calls are missing the required server
UUID argument, causing a signature mismatch with backup.LocateLocal. Update both
call sites in router_server_backup.go that invoke backup.LocateLocal to pass the
current server identifier as the third parameter, using the server UUID already
available in this request flow alongside backupUuid.

In `@server/install.go`:
- Around line 172-181: `SetRestoring` is missing the state update and
`IsInProtectedState` contains misplaced unreachable code; move the
`s.restoring.Store(state)` call back into `SetRestoring` so restore state is
persisted before/after `CancelAll`, and remove the stray line from
`IsInProtectedState` so that method only returns the combined protected-state
check using `IsInstalling`, `IsTransferring`, and `IsRestoring`.

In `@sftp/handler.go`:
- Around line 38-61: Fix the server package build issue before touching
quotaWriterAt: in IsInProtectedState() remove the unreachable
s.restoring.Store(state) and replace the undefined state usage with the correct
restoring flag handling, and in SetRestoring() make sure the restoring state is
actually stored so protected-state checks work. Use the existing
IsInProtectedState and SetRestoring methods in server/install.go as the target
locations.

---

Nitpick comments:
In `@internal/ufs/fs_unix_test.go`:
- Around line 322-333: The symlink timestamp test in the `fs.Chtimes` path only
verifies that the target file’s mtime stays unchanged, but it never checks that
the symlink itself was updated. After calling `fs.Chtimes("link", changed,
changed)`, add an assertion using `os.Lstat("link")` to confirm the link’s own
`ModTime()` matches `changed`, alongside the existing target check, so the
`AT_SYMLINK_NOFOLLOW` behavior is fully covered.

In `@router/router_server_backup.go`:
- Around line 249-256: The UUID canonicalization check in parseBackupUuid
duplicates the same parse/length/lowercase validation already used by
normalizedIdentifier in backup.go. Refactor parseBackupUuid to call a shared
helper (ideally the existing normalizedIdentifier or a common exported utility)
so both validation paths stay identical, while keeping the current
AbortWithStatusJSON behavior on failure.

In `@server/backup/backup.go`:
- Around line 101-133: The canonical backup UUID validation logic is duplicated
between Backup.normalizedIdentifier() and router/router_server_backup.go’s
parseBackupUuid, so extract the parse-plus-canonicalization check into one
shared helper and have both call it. Keep the existing behavior the same, but
move the UUID parsing/length/lowercase validation into a single reusable
function (for example in backup or a small uuidutil helper) so future
canonicalization changes only need to be made in one place.
- Around line 144-146: The new validateIdentifier addition is fine, but the
backup checksum code still uses sha1.New(), which static analysis flags as a
broken hash algorithm. If you choose to address it in this area, update the
checksum path in backup/backup.go to use a non-broken hash implementation and
keep the change coordinated with any panel-side checksum consumers, since the
checksum is used for backup integrity/dedup and must remain compatible.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6045b619-5bed-454b-820c-233cc2894c67

📥 Commits

Reviewing files that changed from the base of the PR and between 1c2070e and 3836f1a.

📒 Files selected for processing (23)
  • config/config.go
  • config/config_docker.go
  • config/onfig_docker_test.go
  • environment/docker/container.go
  • internal/ufs/fs_quota.go
  • internal/ufs/fs_quota_test.go
  • internal/ufs/fs_unix.go
  • internal/ufs/fs_unix_test.go
  • router/router_server_backup.go
  • router/router_server_backup_test.go
  • server/backup/backup.go
  • server/backup/backup_local.go
  • server/backup/backup_s3.go
  • server/backup/backup_test.go
  • server/filesystem/compress.go
  • server/filesystem/disk_space.go
  • server/filesystem/filesystem.go
  • server/filesystem/filesystem_test.go
  • server/filesystem/quota_file.go
  • server/install.go
  • server/state_test.go
  • sftp/handler.go
  • sftp/handler_test.go
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Analyze (go)
⚠️ CI failures not shown inline (5)

GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.25.11, linux, arm64): July upstream changes

Conclusion: failure

View job details

##[group]Run go build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}
 �[36;1mgo build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}�[0m
 �[36;1mgo build -v -trimpath -ldflags="-X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings_debug ${SRC_PATH}�[0m
 �[36;1mchmod 755 dist/*�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GOTOOLCHAIN: local
   GOOS: linux
   GOARCH: arm64
   CGO_ENABLED: 0
   SRC_PATH: github.com/pelican-dev/wings
 ##[endgroup]
 internal/goarch
 internal/unsafeheader
 internal/byteorder
 internal/coverage/rtcov
 internal/cpu
 internal/abi
 internal/godebugs
 internal/goexperiment
 internal/goos
 internal/bytealg
 internal/chacha8rand
 internal/profilerecord
 internal/runtime/atomic
 internal/runtime/math
 internal/runtime/syscall
 internal/runtime/strconv
 internal/runtime/gc
 internal/asan
 internal/msan
 internal/runtime/cgroup
 internal/runtime/exithook
 internal/race
 internal/runtime/sys
 internal/stringslite
 internal/trace/tracev2
 sync/atomic
 internal/synctest
 internal/runtime/maps
 math/bits
 unicode
 unicode/utf8
 internal/sync
 internal/itoa
 cmp
 math
 crypto/internal/fips140/alias
 crypto/internal/fips140deps/byteorder
 crypto/internal/fips140deps/cpu
 crypto/internal/fips140/subtle
 crypto/internal/boring/sig
 container/list
 unicode/utf16
 runtime
 vendor/golang.org/x/crypto/cryptobyte/asn1
 vendor/golang.org/x/crypto/internal/alias
 internal/nettrace
 encoding
 log/internal
 image/color
 github.com/charmbracelet/x/ansi/parser
 github.com/rivo/uniseg
 github.com/charmbracelet/bubbles/runeutil
 github.com/charmbracelet/huh/internal/selector
 github.com/docker/docker/api
 github.com/docker/docker/api/types/common
 github.com/docker/docker/api/types/storage
 github.com/docker/docker/api/types/checkpoint
 log/slog/internal
 go.opentelemetry.io/otel/trace/embedded
 go.opentelemetry.io/otel/metric/embedded
...

GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.26.4, linux, arm64): July upstream changes

Conclusion: failure

View job details

##[group]Run go build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}
 �[36;1mgo build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}�[0m
 �[36;1mgo build -v -trimpath -ldflags="-X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings_debug ${SRC_PATH}�[0m
 �[36;1mchmod 755 dist/*�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GOTOOLCHAIN: local
   GOOS: linux
   GOARCH: arm64
   CGO_ENABLED: 0
   SRC_PATH: github.com/pelican-dev/wings
 ##[endgroup]
 internal/goarch
 internal/unsafeheader
 internal/byteorder
 internal/coverage/rtcov
 internal/cpu
 internal/abi
 internal/godebugs
 internal/goexperiment
 internal/bytealg
 internal/chacha8rand
 internal/goos
 internal/profilerecord
 internal/runtime/atomic
 internal/runtime/syscall/linux
 math/bits
 internal/runtime/gc
 internal/runtime/sys
 internal/asan
 internal/strconv
 internal/runtime/exithook
 internal/msan
 internal/race
 internal/runtime/gc/scan
 internal/runtime/math
 internal/runtime/pprof/label
 internal/runtime/maps
 internal/stringslite
 internal/trace/tracev2
 sync/atomic
 internal/synctest
 unicode
 internal/sync
 internal/runtime/cgroup
 unicode/utf8
 cmp
 crypto/internal/fips140/alias
 crypto/internal/fips140deps/byteorder
 crypto/internal/fips140deps/cpu
 crypto/internal/constanttime
 math
 crypto/internal/fips140/subtle
 crypto/subtle
 crypto/internal/boring/sig
 container/list
 unicode/utf16
 runtime
 vendor/golang.org/x/crypto/cryptobyte/asn1
 vendor/golang.org/x/crypto/internal/alias
 internal/nettrace
 encoding
 log/internal
 image/color
 github.com/rivo/uniseg
 github.com/charmbracelet/bubbles/runeutil
 github.com/charmbracelet/x/ansi/parser
 github.com/charmbracelet/huh/internal/selector
 github.com/docker/docker/api
 github.com/docker/docker/api/types/common
 github.com/docker/docker/api/types/storage
 github.com/docker/docker/api/types/checkpoint
 log/slog/internal...

GitHub Actions: Push / 2_Build and Test (ubuntu-22.04, 1.26.4, linux, arm64).txt: July upstream changes

Conclusion: failure

View job details

##[group]Run go build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}
 �[36;1mgo build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}�[0m
 �[36;1mgo build -v -trimpath -ldflags="-X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings_debug ${SRC_PATH}�[0m
 �[36;1mchmod 755 dist/*�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GOTOOLCHAIN: local
   GOOS: linux
   GOARCH: arm64
   CGO_ENABLED: 0
   SRC_PATH: github.com/pelican-dev/wings
 ##[endgroup]
 internal/goarch
 internal/unsafeheader
 internal/byteorder
 internal/coverage/rtcov
 internal/cpu
 internal/abi
 internal/godebugs
 internal/goexperiment
 internal/bytealg
 internal/chacha8rand
 internal/goos
 internal/profilerecord
 internal/runtime/atomic
 internal/runtime/syscall/linux
 math/bits
 internal/runtime/gc
 internal/runtime/sys
 internal/asan
 internal/strconv
 internal/runtime/exithook
 internal/msan
 internal/race
 internal/runtime/gc/scan
 internal/runtime/math
 internal/runtime/pprof/label
 internal/runtime/maps
 internal/stringslite
 internal/trace/tracev2
 sync/atomic
 internal/synctest
 unicode
 internal/sync
 internal/runtime/cgroup
 unicode/utf8
 cmp
 crypto/internal/fips140/alias
 crypto/internal/fips140deps/byteorder
 crypto/internal/fips140deps/cpu
 crypto/internal/constanttime
 math
 crypto/internal/fips140/subtle
 crypto/subtle
 crypto/internal/boring/sig
 container/list
 unicode/utf16
 runtime
 vendor/golang.org/x/crypto/cryptobyte/asn1
 vendor/golang.org/x/crypto/internal/alias
 internal/nettrace
 encoding
 log/internal
 image/color
 github.com/rivo/uniseg
 github.com/charmbracelet/bubbles/runeutil
 github.com/charmbracelet/x/ansi/parser
 github.com/charmbracelet/huh/internal/selector
 github.com/docker/docker/api
 github.com/docker/docker/api/types/common
 github.com/docker/docker/api/types/storage
 github.com/docker/docker/api/types/checkpoint
 log/slog/internal...

GitHub Actions: Push / 1_Build and Test (ubuntu-22.04, 1.25.11, linux, arm64).txt: July upstream changes

Conclusion: failure

View job details

##[group]Run go build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}
 �[36;1mgo build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}�[0m
 �[36;1mgo build -v -trimpath -ldflags="-X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings_debug ${SRC_PATH}�[0m
 �[36;1mchmod 755 dist/*�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GOTOOLCHAIN: local
   GOOS: linux
   GOARCH: arm64
   CGO_ENABLED: 0
   SRC_PATH: github.com/pelican-dev/wings
 ##[endgroup]
 internal/goarch
 internal/unsafeheader
 internal/byteorder
 internal/coverage/rtcov
 internal/cpu
 internal/abi
 internal/godebugs
 internal/goexperiment
 internal/goos
 internal/bytealg
 internal/chacha8rand
 internal/profilerecord
 internal/runtime/atomic
 internal/runtime/math
 internal/runtime/syscall
 internal/runtime/strconv
 internal/runtime/gc
 internal/asan
 internal/msan
 internal/runtime/cgroup
 internal/runtime/exithook
 internal/race
 internal/runtime/sys
 internal/stringslite
 internal/trace/tracev2
 sync/atomic
 internal/synctest
 internal/runtime/maps
 math/bits
 unicode
 unicode/utf8
 internal/sync
 internal/itoa
 cmp
 math
 crypto/internal/fips140/alias
 crypto/internal/fips140deps/byteorder
 crypto/internal/fips140deps/cpu
 crypto/internal/fips140/subtle
 crypto/internal/boring/sig
 container/list
 unicode/utf16
 runtime
 vendor/golang.org/x/crypto/cryptobyte/asn1
 vendor/golang.org/x/crypto/internal/alias
 internal/nettrace
 encoding
 log/internal
 image/color
 github.com/charmbracelet/x/ansi/parser
 github.com/rivo/uniseg
 github.com/charmbracelet/bubbles/runeutil
 github.com/charmbracelet/huh/internal/selector
 github.com/docker/docker/api
 github.com/docker/docker/api/types/common
 github.com/docker/docker/api/types/storage
 github.com/docker/docker/api/types/checkpoint
 log/slog/internal
 go.opentelemetry.io/otel/trace/embedded
 go.opentelemetry.io/otel/metric/embedded
...

GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.25.11, linux, amd64): July upstream changes

Conclusion: failure

View job details

##[group]Run go build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}
 �[36;1mgo build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}�[0m
 �[36;1mgo build -v -trimpath -ldflags="-X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings_debug ${SRC_PATH}�[0m
 �[36;1mchmod 755 dist/*�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GOTOOLCHAIN: local
   GOOS: linux
   GOARCH: amd64
   CGO_ENABLED: 0
   SRC_PATH: github.com/pelican-dev/wings
 ##[endgroup]
 internal/unsafeheader
 internal/byteorder
 internal/goarch
 internal/coverage/rtcov
 internal/godebugs
 internal/goexperiment
 internal/goos
 internal/profilerecord
 internal/runtime/math
 internal/runtime/strconv
 internal/cpu
 internal/runtime/atomic
 internal/runtime/syscall
 internal/abi
 internal/runtime/gc
 internal/asan
 internal/msan
 internal/bytealg
 internal/chacha8rand
 internal/runtime/exithook
 internal/runtime/sys
 internal/trace/tracev2
 internal/runtime/cgroup
 internal/stringslite
 sync/atomic
 math/bits
 unicode
 internal/race
 internal/synctest
 internal/runtime/maps
 unicode/utf8
 internal/sync
 internal/itoa
 cmp
 crypto/internal/fips140/alias
 math
 crypto/internal/fips140deps/byteorder
 crypto/internal/fips140deps/cpu
 crypto/internal/fips140/subtle
 crypto/internal/boring/sig
 container/list
 unicode/utf16
 vendor/golang.org/x/crypto/cryptobyte/asn1
 vendor/golang.org/x/crypto/internal/alias
 internal/nettrace
 encoding
 log/internal
 image/color
 github.com/rivo/uniseg
 runtime
 github.com/charmbracelet/x/ansi/parser
 github.com/charmbracelet/bubbles/runeutil
 github.com/charmbracelet/huh/internal/selector
 github.com/docker/docker/api
 github.com/docker/docker/api/types/common
 github.com/docker/docker/api/types/storage
 github.com/docker/docker/api/types/checkpoint
 log/slog/internal
 go.opentelemetry.io/otel/trace/embedded
 go.opentelemetry.io/otel/metric/embedded
...
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-03-02T13:53:08.995Z
Learnt from: parkervcp
Repo: pelican-dev/wings PR: 171
File: server/power.go:190-203
Timestamp: 2026-03-02T13:53:08.995Z
Learning: In the server package, when quotas are enabled via config.Get().System.Quotas.Enabled, the disk space check using used >= s.DiskSpace() does not require a special guard for unlimited-disk scenarios (DiskSpace() <= 0). The filesystem handles such cases, so the existing check is sufficient. Apply this pattern to similar quota-related disk checks in the server package and ensure tests/docs reflect that unlimited-disk behavior is governed by the filesystem, not by an extra guard in code.

Applied to files:

  • server/state_test.go
  • server/backup/backup_s3.go
  • server/backup/backup_test.go
  • server/filesystem/quota_file.go
  • server/filesystem/filesystem.go
  • server/backup/backup_local.go
  • server/filesystem/compress.go
  • server/filesystem/filesystem_test.go
  • server/filesystem/disk_space.go
  • server/install.go
  • server/backup/backup.go
🪛 ast-grep (0.44.0)
server/backup/backup.go

[warning] 146-146: SHA-1 is a cryptographically broken hash function vulnerable to collision attacks and is unsuitable for security purposes such as signatures, integrity checks, or password hashing. Use a SHA-2 family function (e.g. sha256.New() / sha256.Sum256()) or SHA-3 instead.
Context: sha1.New
Note: [CWE-327] Use of a Broken or Risky Cryptographic Algorithm.

(weak-hash-sha1-go)

🪛 GitHub Actions: Push / 0_Build and Test (ubuntu-22.04, 1.26.4, linux, amd64).txt
environment/docker/container.go

[error] 393-393: Go build failed: undefined: img (at environment/docker/container.go:393:76). Command: go build -v -trimpath -ldflags="-s -w -X ${SRC_PATH}/system.Version=dev-${GITHUB_SHA:0:7}" -o dist/wings ${SRC_PATH}

🪛 GitHub Actions: Push / 1_Build and Test (ubuntu-22.04, 1.25.11, linux, arm64).txt
environment/docker/container.go

[error] 393-393: go build failed: environment/docker/container.go:393:76: undefined: img

🪛 GitHub Actions: Push / 2_Build and Test (ubuntu-22.04, 1.26.4, linux, arm64).txt
environment/docker/container.go

[error] 393-393: Go build failed: undefined: img (environment/docker/container.go:393:76)

🪛 GitHub Actions: Push / 3_Build and Test (ubuntu-22.04, 1.25.11, linux, amd64).txt
environment/docker/container.go

[error] 393-393: go build failed: undefined: img (environment/docker/container.go:393:76)

🪛 GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.25.11, linux, amd64)
environment/docker/container.go

[error] 393-393: go build failed: undefined: img

🪛 GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.25.11, linux, arm64)
environment/docker/container.go

[error] 393-393: go build failed: container.go:393:76: undefined: img

🪛 GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.26.4, linux, amd64)
environment/docker/container.go

[error] 393-393: go build failed: undefined: img (environment/docker/container.go:393:76).

🪛 GitHub Actions: Push / Build and Test (ubuntu-22.04, 1.26.4, linux, arm64)
environment/docker/container.go

[error] 393-393: go build failed: undefined: img (environment/docker/container.go:393:76).

🪛 GitHub Check: Build and Test (ubuntu-22.04, 1.25.11, linux, amd64)
environment/docker/container.go

[failure] 393-393:
undefined: img

🪛 GitHub Check: Build and Test (ubuntu-22.04, 1.25.11, linux, arm64)
environment/docker/container.go

[failure] 393-393:
undefined: img

🪛 GitHub Check: Build and Test (ubuntu-22.04, 1.26.4, linux, amd64)
environment/docker/container.go

[failure] 393-393:
undefined: img

🪛 GitHub Check: Build and Test (ubuntu-22.04, 1.26.4, linux, arm64)
environment/docker/container.go

[failure] 393-393:
undefined: img

🪛 golangci-lint (2.12.2)
environment/docker/container.go

[error] 393-393: : # github.com/pelican-dev/wings/environment/docker
environment/docker/container.go:393:76: undefined: img

(typecheck)

🔇 Additional comments (29)
config/config_docker.go (1)

114-199: LGTM!

config/onfig_docker_test.go (1)

1-99: LGTM!

server/install.go (1)

204-204: LGTM!

Also applies to: 259-261

server/state_test.go (1)

5-47: Test correctly targets state cancellation, but depends on a currently broken package.

Per the referenced server/install.go contract snippets, IsInProtectedState/SetRestoring currently contain a bug that breaks compilation of package server — see the detailed comment in sftp/handler.go (lines 38-61, 327). This test cannot pass/build until that root cause is fixed.

sftp/handler.go (3)

106-108: Whitespace-only changes, no functional impact.

Also applies to: 135-137, 181-184


128-128: 🚀 Performance & Scalability

Verify the cost of forcing a fresh disk-usage scan on every SFTP write open.

HasSpaceAvailable(true)HasSpaceAvailable(false) forces DiskUsage to skip the cached value on every Filewrite call. Given quota is now also enforced at the lower quotaFile level (per the stack's "Overflow-safe disk quota" cohort), confirm this eager recompute is intentional and its cost (e.g., directory walk) is acceptable on the SFTP hot path, rather than a leftover from before the low-level enforcement existed.


43-53: LGTM!

Also applies to: 55-60, 121-169, 326-329

sftp/handler_test.go (2)

36-41: "restoring" subtests depend on the same root-cause bug flagged in sftp/handler.go.

Once IsInProtectedState/SetRestoring are fixed (see comment on sftp/handler.go lines 38-61), these subtests should pass as written; until then they will fail/fail to compile.

Also applies to: 81-86


1-18: LGTM!

Also applies to: 19-35, 42-80, 87-140

internal/ufs/fs_quota.go (2)

71-97: LGTM!


121-129: LGTM!

internal/ufs/fs_quota_test.go (1)

8-47: LGTM!

server/filesystem/disk_space.go (2)

168-202: LGTM!


211-240: LGTM!

server/filesystem/quota_file.go (2)

23-112: LGTM!


11-21: 🩺 Stability & Availability

No quota bypass here — current Touch call paths only write/close the returned handle; none call a promoted Truncate, so this wrapper does not expose a reachable quota bypass.

			> Likely an incorrect or invalid review comment.
server/filesystem/filesystem.go (1)

98-111: LGTM!

server/filesystem/compress.go (2)

156-159: LGTM!


247-259: LGTM!

server/filesystem/filesystem_test.go (2)

115-196: LGTM!


268-279: LGTM!

internal/ufs/fs_unix_test.go (1)

16-16: LGTM!

internal/ufs/fs_unix.go (1)

173-174: 🎯 Functional Correctness

No internal caller depends on the old symlink-following Chtimes behavior.

server/backup/backup_local.go (1)

38-53: LGTM!

Also applies to: 56-75, 84-110, 114-142

server/backup/backup_s3.go (1)

42-47: LGTM!

Also applies to: 56-94

server/backup/backup_test.go (1)

1-103: LGTM!

config/config.go (1)

293-297: LGTM!

router/router_server_backup.go (1)

4-36: Solid SSRF hardening design.

The blocked-IP checks, per-connection DNS resolution + validation in the custom DialContext, redirect re-validation, and content-type allowlisting together form a robust defense against SSRF via DNS rebinding and redirect chains — the "fail closed if any resolved IP is unsafe" behavior in the dial loop is a good touch.

Also applies to: 39-81, 92-106, 181-216, 258-370

router/router_server_backup_test.go (1)

1-337: Good test coverage for the new restore hardening logic; contingent on the LocateLocal fix.

This test suite (loopback rejection, non-UUID rejection, bad status, content-type validation, UUID parsing, allowlist) is thorough and directly exercises postServerRestoreBackup. Note that if the backup.LocateLocal argument-count issue flagged in router_server_backup.go is real, these tests wouldn't currently compile/pass — see that file's review comments.

Comment thread environment/docker/container.go Outdated
Comment thread router/router_server_backup.go
Comment thread router/router_server_backup.go
Comment thread server/install.go
Comment thread sftp/handler.go
@QuintenQVD0

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@router/router_server_backup_test.go`:
- Around line 86-88: The backup test helper’s PushServerStateChange method
references an undefined ServerStateChange type, causing the router test package
to fail typecheck. Update backupTestRemoteClient.PushServerStateChange to use
the correct fully qualified type or add the missing import/alias for the actual
ServerStateChange definition used elsewhere in the router package, and ensure
the method signature matches the remote client interface exactly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9eda69fd-76e8-430c-990d-6b80f1e02511

📥 Commits

Reviewing files that changed from the base of the PR and between e826780 and be4335f.

📒 Files selected for processing (1)
  • router/router_server_backup_test.go
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: Analyze (go)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.26.4, linux, amd64)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.26.4, linux, arm64)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.25.11, linux, arm64)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.25.11, linux, amd64)
🧰 Additional context used
🪛 golangci-lint (2.12.2)
router/router_server_backup_test.go

[error] 86-86: : # github.com/pelican-dev/wings/router [github.com/pelican-dev/wings/router.test]
router/router_server_backup_test.go:86:80: undefined: ServerStateChange

(typecheck)

Comment thread router/router_server_backup_test.go Outdated
@QuintenQVD0 QuintenQVD0 requested a review from parkervcp July 4, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant