Skip to content

July upstream changes - #195

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

July upstream changes#195
QuintenQVD0 wants to merge 17 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 configurable host, IP, and CIDR allowlists for remote backup restores.
    • Improved Docker registry credential selection for images using domain and path matching.
    • Added disk-quota enforcement for file writes and file handle operations.
  • Bug Fixes

    • Hardened backup creation, deletion, and restoration against invalid identifiers and unsafe download URLs.
    • Prevented quota overflows and incorrect usage accounting.
    • SFTP writes are now blocked while servers are installing, transferring, or restoring.
    • Improved filesystem timestamp and archive space handling.

@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

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds registry credential matching, overflow-safe filesystem quota accounting, protected-state SFTP controls, canonical backup UUID validation, hardened remote restore downloads, and symlink timestamp tests.

Changes

Docker registry credential resolution

Layer / File(s) Summary
Registry matching and pull integration
config/config_docker.go, config/config_docker_test.go, environment/docker/container.go, server/install.go
Registry references are normalized and matched by domain and path. Container and installation image pulls use the matched credentials. Tests cover domains, ports, paths, Docker Hub, and sibling paths.

Overflow-safe disk quota and quota-aware file writes

Layer / File(s) Summary
Overflow-safe quota arithmetic
internal/ufs/fs_quota.go, internal/ufs/fs_quota_test.go
Quota updates use saturating CAS arithmetic. Capacity checks avoid overflow.
Disk reservation and usage adjustment
server/filesystem/disk_space.go
Filesystem accounting adds capacity-checked reservation and adjustment helpers.
Quota-aware filesystem handles
server/filesystem/quota_file.go, server/filesystem/filesystem.go, server/filesystem/filesystem_test.go
File handles enforce quota during writes, copies, touch operations, and close-time reconciliation.
Overflow-safe archive space checks
server/filesystem/compress.go, server/filesystem/filesystem_test.go
Archive capacity checks reject negative sizes and guard accumulated size overflow.

Protected server state blocks SFTP writes

Layer / File(s) Summary
Protected-state transitions
server/install.go, server/state_test.go
Installing, transferring, and restoring states cancel SFTP activity.
SFTP permission and write enforcement
sftp/handler.go, sftp/handler_test.go
Protected states deny permissions and active writes. Disk-space errors map to the SFTP quota error.

Backup UUID validation and hardened restore downloads

Layer / File(s) Summary
Backup identifier validation
server/backup/backup.go, server/backup/backup_local.go, server/backup/backup_s3.go, server/backup/backup_test.go
Backup operations validate canonical UUIDs before filesystem or archive operations.
Restore request and download validation
config/config.go, router/router_server_backup.go, router/router_download.go
Restore endpoints validate UUIDs and URLs, apply destination allowlists, restrict content types, and use hardened HTTP transport.
Restore validation coverage
router/router_server_backup_test.go
Tests cover UUIDs, response status, MIME types, blocked destinations, allowlists, and client settings.

Symlink-safe timestamp updates

Layer / File(s) Summary
Timestamp update tests
internal/ufs/fs_unix_test.go
Tests cover regular-file timestamps and symlink target preservation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RestoreRequest
  participant RestoreHTTPClient
  participant RemoteBackupHost
  participant BackupStorage
  RestoreRequest->>RestoreHTTPClient: Validate and download backup URL
  RestoreHTTPClient->>RemoteBackupHost: Resolve host and request archive
  RemoteBackupHost-->>RestoreHTTPClient: Return HTTP response and gzip archive
  RestoreHTTPClient->>BackupStorage: Pass validated archive to restore
Loading

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: parkervcp

Poem

I thumped through quotas, safe and bright,

And checked each backup path at night.
Registry doors now match just right,
SFTP rests when states turn tight.
Hop, hop—no symlink strays from sight! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title identifies an upstream change but does not describe the primary changes, such as backup restore validation, quota handling, or protected server states. Replace the title with a concise summary of the primary changes, such as “Add backup restore validation and quota safety improvements.”
✅ 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 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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