Commit Graph

39 Commits (5ebc1af91e96ca065ea55f20e94de5d874a442c8)

Author SHA1 Message Date
Your Name 5ebc1af91e BATCH 1 7 days ago
Shlee 2eb13c901b
Update CaptchaEnableCommand.php 7 days ago
Your Name 648a901aae polish 1 week ago
Your Name 729396302a fix(federation): swallow ConnectionException on synchronous AP delivery
queueDelivery() runs synchronously from the v1 follow/unfollow endpoints
(via Helpers::sendSignedObject), which commit local state before delivery
and have no try/catch. After the Http::send() rewrite, a ConnectionException
from a momentarily-unreachable remote was rethrown out of queueDelivery(),
turning a best-effort delivery into a 500 for the user after the follow/
unfollow was already persisted. For unfollows, a retry then hit the
isFollowing==false branch and never re-sent the Undo, diverging state.

Treat transport failures (ConnectionException) as best-effort on this
single-delivery path: log, record host health, and return without
propagating. Other exception types (invalid sender/destination, signing,
serialization) still throw, matching pre-rewrite precondition behavior.

Also widen SendUpdateActor's per-user catch from HttpException to Throwable
so a single bad host no longer aborts a fleet-wide actor update (the old
HttpException catch is dead for ConnectionException/invalid-destination).
2 weeks ago
Your Name 341351c47e Remove sha256 verification from MediaMoveStorageLocalToCloud
original_sha256 is the pre-optimization upload hash and can never match the
optimized local file, so comparing against it is not a valid integrity
check for migration. Drop the --verify-sha256 option and the checksum step
entirely; verify now relies on cloud-object existence and size parity.
2 weeks ago
Your Name 438560415a Revert debug-by-default in MediaMoveStorageLocalToCloud
The cloud migration failure (stale original_sha256 verify) is resolved, so
the temporary default-on debug is no longer needed. Restore --debug to a
bare, off-by-default flag and remove the debugEnabled() string-parsing
helper.
2 weeks ago
Your Name 441a94e731 Make original_sha256 verify opt-in in MediaMoveStorageLocalToCloud
original_sha256 is the hash of the file as originally uploaded, but the
async optimize pipeline (ImageResize/ImageUpdate) rewrites the local file
in place and never updates that column. Verifying the current local bytes
against it made every optimized image fail with sha256_mismatch, so the
migration reported moved=0 and exited 1.

Add a --verify-sha256 flag (off by default) that gates the checksum step.
By default verify relies on cloud-object existence and size parity, which
is the only signal that actually describes the uploaded copy. Add tests
covering both the default (migrates) and opt-in (fails) paths.
2 weeks ago
Your Name b2a068b934 polish 2 weeks ago
Your Name 0c68b6a680 Add failure logging to admin:MediaMoveStorageLocalToCloud and enable debug by default
The scheduled command only surfaced 'exit code 1' with no cause. Add
structured Log::error entries at every failure path (cloud disk
unresolvable/unconfigured, cloud storage disabled, invalid --before-id,
candidate fetch failure, per-media failure with full context, and a
run-level summary when failures occur).

Also make --debug default to true (now a valued option) so production
runs emit verbose routing detail while this is investigated; pass
--debug=false to silence.
2 weeks ago
Daniel Supernault f37c5fc95c
Add notification gc 2 weeks ago
Daniel Supernault 896342a57f
Update MediaMoveStorageLocalToCloud.php 2 weeks ago
Daniel Supernault 85fec3ac82
Create PruneOldNotifications.php 2 weeks ago
Your Name b8ca4da3a6 Add per-file transfer output and --debug detail to MediaMoveStorageLocalToCloud 3 weeks ago
Your Name 6b14b229d1 Fix media storage migration crash when no .env file exists
The media storage migration commands read/parsed the .env file directly to
check and flip PF_ENABLE_CLOUD. In containerized deploys there is no .env on
disk (config is injected via env vars), so updateEnvFile() threw
'file_get_contents(.env): Failed to open stream' and the scheduled command
exited 1.

- Check the live setting via config_cache('pixelfed.cloud_storage') like the
  rest of the app, instead of parsing .env.
- Make the .env write best-effort in ManagesMediaStorageEnv: skip gracefully
  when the file is missing or read-only, and still apply the runtime + DB
  config-cache updates (the load-bearing changes on a hot server).
- Apply the same fix to the sibling unstable:MediaMoveStorageCloudToLocal.
- Add a regression test covering the no-.env container scenario.
3 weeks ago
Your Name 9214e9680a Add admin:resyncemoji command to re-download remote emoji locally
Adds CustomEmojiService::resync() which re-fetches a remote custom emoji's
media from its origin (image_remote_url) via the SSRF-hardened
SecureMediaFetchService and stores it locally under public/{media_path},
reusing the existing headCheck validation and cache busting.

The admin:resyncemoji command takes a comma-separated list of emoji
filenames, looks each up by media_path, and resyncs remote ones. Supports
--missingonly, --dry-run and --force.
4 weeks ago
Your Name a81270770c refactor: keep MediaMoveStorageLocalToCloud as a stable admin command
MediaMoveStorageLocalToCloud is stable, so move it back out of the Unstable
namespace: restore App\Console\Commands\Admin\MediaMoveStorageLocalToCloud and
its admin:MediaMoveStorageLocalToCloud signature, and update the scheduler,
README, and feature test. CloudToLocal and CloudToCloud remain under unstable:.
4 weeks ago
Your Name 41c9b8830f refactor: rename MigrateLocalS3MediaURL class and move media move-storage commands to unstable
- Rename App\Console\Commands\Admin\MigrateLocalS3MediaURL to MediaUpdateS3CDNUrl
  (class + filename only; the admin:MigrateLocalS3MediaURL signature is unchanged)
- Move the three MediaMoveStorage{LocalToCloud,CloudToLocal,CloudToCloud} commands
  into App\Console\Commands\Admin\Unstable and change their signatures from
  admin: to unstable:
- Update the scheduler in bootstrap/app.php, the command README, the
  config/filesystems.php reference comment, and the affected feature tests
4 weeks ago
Your Name 40b323bca4 revert: remove emoji local-to-cloud storage changes
Back out all emoji cloud-storage work from staging so it can be reworked and
re-landed separately (the URL resolution flips to cloud on a global config
flag, which created a broken-URL window, and the migration approach needs
revisiting).

Reverts to pre-emoji state:
- CustomEmoji model URL/storage helpers (urlForPath, storageTarget, storeMedia,
  storeMediaFromFile, deleteMedia, url) and callers in ImportEmojis,
  CustomEmojiService, AdminController
- admin custom-emoji blade views back to local /storage URLs
- Remove admin:EmojiMoveStorageLocalToCloud command
- Remove the deploy migration and its scheduler entry

Media (and the already-reverted story) scheduler entries are untouched.
4 weeks ago
Shlee 948da00f0c
Update EmojiMoveStorageLocalToCloud.php 4 weeks ago
Shlee ef8cf16cfa
Merge pull request #6968 from pixelfed/debug/emoji-cloud-migration
perf: async S3 SDK upload path for emoji migration
4 weeks ago
Your Name a0a262f07f perf: async S3 SDK upload path for emoji migration
Process-level workers plateaued at ~7.5 uploads/sec against Fastly Object
Storage because each PUT is high-latency and only a handful ran concurrently.

Add --concurrency=N which uses the AWS SDK CommandPool to keep N PutObject
requests in flight from a single process. A successful PutObject response is
the confirmation (no separate HEAD verify), and the local file is deleted on
success. Commands are yielded lazily so memory stays flat over large runs.

--no-acl escape hatch for S3-compatible stores that reject the ACL header.
4 weeks ago
Shlee 2c0fe5db2f
Merge pull request #6967 from pixelfed/debug/emoji-cloud-migration
feat: add uploads/sec throughput counter to emoji migration
4 weeks ago
Your Name f17a88e16c feat: add uploads/sec throughput counter to emoji migration
- Live 'up/s' rate shown on the progress bar during single-worker runs
- Final summary reports elapsed time and uploads/sec
- Parallel runs tally moved across workers and report aggregate uploads/sec

Makes it easy to compare --workers counts and decide whether async S3
(option 2) is worth pursuing.
4 weeks ago
Shlee 67ae799cb4
Merge pull request #6966 from pixelfed/debug/emoji-cloud-migration
perf: parallelise emoji cloud migration with worker processes
4 weeks ago
Your Name 00564ac221 perf: parallelise emoji cloud migration with worker processes
The migration was ~1-2s/file due to sequential S3 round-trips (HEAD + PUT +
verify HEAD). Speed it up:

- --workers=N spawns N child processes, each handling a strided slice of the
  files (index % N == shard) for real concurrency on the I/O-bound uploads
- --skip-cloud-check skips the upfront HEAD (always upload, idempotent)
- --skip-verify skips the post-upload size re-check
- --offset for manual chunking

Storage/Flysystem has no batch or async upload API, so process-level
concurrency is the pragmatic lever here.
4 weeks ago
Shlee b6e8571009
Merge pull request #6965 from pixelfed/debug/emoji-cloud-migration
fix: skip missing.png in emoji cloud migration
4 weeks ago
Your Name 9e5fcb9a90 fix: skip missing.png in emoji cloud migration
The frontend renders a hardcoded /storage/emoji/missing.png local onerror
fallback for emoji, so that placeholder must stay on local disk. Skip it in
the migration so it is never moved to cloud or deleted locally.
4 weeks ago
Shlee e79d5c828b
Merge pull request #6964 from pixelfed/debug/emoji-cloud-migration
fix: make emoji cloud migration disk-driven + add --debug
4 weeks ago
Your Name 79eef56be0 fix: make emoji cloud migration disk-driven + add --debug
The migration was DB-driven (whereNull('uri')), which excluded federated
emoji whose media is stored locally but have a uri set -> the disk was never
scanned, resulting in moved=0.

- Drive the migration by enumerating local files under public/emoji/ instead
  of a DB query; the local file is the source of truth for what needs moving
- Add --debug to print config, custom_emoji table breakdown, local emoji dir
  contents, and per-file decisions
4 weeks ago
Your Name 9f55f7204c revert: story cloud-migration work
Back out the story local->cloud migration so we can land and verify the
emoji cloud work first, one change at a time.

Reverts:
- 9f110bb74 feat: migrate local story media to cloud storage
- 842681b99 fix: schedule StoryMoveStorageLocalToCloud command

Removes StoryMoveStorageLocalToCloud command, its scheduler entry, and the
StoryExpire explicit-disk changes. Remcache and emoji work are untouched.
Will revisit story once emoji is confirmed.
4 weeks ago
Your Name aa9bb868dd fix: emoji admin URLs and cloud-migration guard
Two issues prevented emoji from serving/migrating correctly on cloud:

- Admin custom-emoji views hardcoded url('storage/'.media_path), so they
  always showed local URLs and bypassed cloud resolution. Use $emoji->url().
- The migration/command guard relied solely on config_cache('pixelfed.cloud_storage'),
  which is DB/12h-cached and can read stale-false right after cloud is
  enabled, causing the migration to silently no-op. Treat cloud as enabled
  when either live config() or config_cache() is true.
4 weeks ago
Your Name 979df6e39e feat: migrate all local emoji to cloud in one pass by default
Change --limit default to 0 (no limit) so the emoji migration processes
every local emoji in a single run instead of capping at 1000, and drop the
limit from the scheduled invocation. Avoids a multi-run window where
not-yet-migrated emoji resolve to missing cloud URLs.
4 weeks ago
Your Name fa76e1014a feat: store custom emoji on cloud storage when enabled
Custom emoji were always written locally and served via hardcoded /storage
URLs, so they never used S3 even on cloud instances.

- CustomEmoji: centralize URL + storage on the active disk (cloud when
  pixelfed.cloud_storage is enabled, else local public/ disk) via
  urlForPath/url/storageTarget/storeMedia/storeMediaFromFile/deleteMedia
- Route emoji writes/deletes and URL generation (scan, CustomEmojiService::all)
  through those helpers in ImportEmojis, CustomEmojiService::import and
  AdminController
- Add admin:EmojiMoveStorageLocalToCloud to migrate existing local emoji to
  cloud: copy, verify by size, delete local, bust caches
- Schedule it daily when cloud storage is enabled
4 weeks ago
Your Name 9f110bb74c feat: migrate local story media to cloud storage
Ensure story media lands on and stays on cloud storage for S3 instances.

- StoryExpire: archive expiring story media on the same explicit disk the
  media lives on (S3 move is a server-side copy+delete), with error handling
- Add admin:StoryMoveStorageLocalToCloud to migrate local story media
  (active + story_archives) to cloud: copy, verify by size, then delete local
- --orphans option relocates untracked story_archives/ files to cloud using
  the same copy/verify/delete flow (media is moved, never discarded)
- Schedule it hourly alongside the media migration when cloud storage is on
4 weeks ago
Your Name 878775cab9 chore: resolve psalm issues in admin commands and auth
- Add return type hints (void) and final class markers
- Guard null returns from newestBackup() and putFileAs() in BackupToCloud
- Type ask() default values as strings
- Fix uses_left fallback condition for null/zero max_uses
- Annotate AdminInvite::whereInviteCode and cast Str::uuid() to string
- Ignore local redis-data and mysql-9-data dev directories
4 weeks ago
Your Name de850836ca fix: make admin:fixPostCounts summary report only changed metrics
The resynced summary printed all three counts unconditionally, which
made an untouched metric (e.g. an already-correct comments count) look
like it had been resynced. Drive the summary from the drifted set and
show before->after values, so it matches the drift detection exactly.
4 weeks ago
Your Name d50024a578 fix: display comments count as 0 instead of blank in admin:fixPostCounts
reply_count is a nullable column, so NULL rendered as an empty string in
the resync summary. Cast the summary output to int so a null/absent
comment count prints as 0. No behavior change to the reconcile logic.
4 weeks ago
Your Name 73b8353dab refactor: move admin:fix*Counts commands to Admin/
FixProfileCounts and FixPostCounts use the admin: signature prefix and
are operator-run maintenance tools, so move them from FixBugs/ to Admin/
(namespace updated) and refresh the README tables to match.
4 weeks ago
Your Name 1eae4bbd43 refactor: organize Artisan commands into subfolders
Group console commands into Admin, Dev, FixBugs, Install, Internal, and
User subfolders (matching the earlier reorganization), and add a new
Status subfolder for the status:user, status:profile, and status:post
debug commands. Namespaces updated to match; command signatures and the
total command count are unchanged.
4 weeks ago