Complete the galaxyproject.eu → hub redirect map#2198
Conversation
Extend the galaxyproject.eu server block with the full legacy URL to galaxyproject.org redirect table derived from the EU website migration audit manifest, completing the work started in #421. All 1308 routable legacy records are covered: 574 news posts and 258 events get exact `location =` rules pointing at their verified hub page, subdomain landing pages, core EU pages and member subsites are handled by deterministic regex rules, and un-migrated content (chiefly the ~222 autogenerated tool-update posts) collapses to the news index per the redirect table in galaxyproject/galaxy-hub#1480. Exact blocks rather than a single regex transform are required because the hub does not normalise slugs -- uppercase, camelCase, underscore and re-dated event URLs all 404 -- and stock nginx cannot lower-case in a rewrite. Regexes that interpolate a capture into their target are therefore case-sensitive; the rest are case-insensitive and tolerant of a trailing slash and of the legacy .html suffix, following #2108. Two rewrites fold the plain.html, -plain and event.ics variants onto the canonical path so one rule per item suffices. Unmatched paths now land on /eu/ instead of being proxied to usegalaxy-eu.github.io. Verified with nginx -t and by replaying all 5613 legacy URLs against a local nginx: every one returns 301, and all 906 distinct targets resolve on galaxyproject.org (zero 404s).
The audit manifest marks these 89 posts and 44 events as `migrated` and the hub content exists and serves 200, but no exact `location =` rule was generated for them, so they fell through to the blanket index redirect (/news/ or /eu/events/) instead of reaching their article. Targets are lower-cased: the hub lower-cases published slugs. Three manifest entries were mis-cased and 404 as recorded -- /events/2022-11-BH2022/ and /events/2022-10-PSU-Workshop/ -- their lower-cased forms are 200. All 133 targets were verified live before being written. Exact rules: 832 -> 965 (posts 574 -> 663, events 258 -> 302).
Every exact `location =` block is keyed on a trailing-slash URL, but the legacy host also answers the slashless form: GitHub Pages 301s /posts/2018/10/08/gxadmin -> /posts/2018/10/08/gxadmin/, so slashless URLs are real, linked and working in the wild. A slashless request matched no exact block and fell through to the blanket index redirect, silently bypassing the entire 965-rule table. Two server-level rewrites fold the slashless and .html forms onto the canonical key, following the existing plain/ics folding pattern. `[^/]+?` cannot match a trailing slash, so a rewritten URI cannot re-enter these rules and no rewrite loop is possible. The .html form 404s on the legacy host today (posts and events are directory -style URLs); folding it is defensive and can only upgrade a dead URL. Verified against a live nginx: slashless, trailing-slash, .html, -plain, /plain.html and /event.ics variants all resolve to the article, dotted slugs (Galaxy-17.09) survive normalisation, and unmigrated tool-update posts still reach the blanket rule.
The overrides for index-microbiome, index-ssh and index-test were keyed only on the .html and trailing-slash forms, so the BARE form -- which is the canonical published URL (/index-ssh 200, /index-ssh/ 404 on the legacy host) -- fell through to the generic index- rule and was sent to /bare/eu/usegalaxy/<name>/, which 404s on the hub. All three were broken-target. Replaces the six exact blocks (two of which were dead: the trailing-slash URLs were never published) with three regex blocks covering the bare, .html and trailing-slash forms in one place, ordered ahead of the generic rule. index-microbiome.md is a symlink to index-metagenomics.md in the legacy repo, so it is the metagenomics page; content/redirects.yaml in the hub independently declares the same target. Verified 200. index-ssh and index-test have no hub counterpart -- index-ssh does not even exist in the legacy source tree, only in the deployed branch -- so they point at the EU landing page and are recorded as content gaps.
All 467 legacy asset URLs hit the catch-all and 301 to /eu/, so an image request is answered with a 52 KB HTML page at HTTP 200. That is strictly worse than a 404: no client or crawler can detect the breakage, and every legacy hotlink -- in third-party pages, archived posts and Galaxy tool help text -- renders as a broken image. 163 of them exist on the hub at the identical path, so a single prefix rule recovers them (/assets/media/tk_besoek.jpg -> 200 image/jpeg, verified). The remaining ~290 now 404 honestly. css/, fonts/ and js/ are deliberately included rather than carved out: none exist on the hub, but a 301 that ends in a 404 is a truthful answer whereas the catch-all returns 200 text/html for a stylesheet.
Feeds first -- these are subscription endpoints, and a 301 to an HTML page
breaks every reader silently:
/feed.xml -> /eu/feed.atom (jekyll-feed site-wide posts feed;
RSS -> Atom, readers follow the 301)
/events-ical -> /eu/events/calendar.ics (legacy served this as text/html, so
strict clients never worked; the hub
serves real text/calendar)
Per-event /event/<slug>/event.ics keeps folding to the event page rather than
to the EU calendar: that calendar holds only the 12 upcoming events, so a
request for a 2022 event would import unrelated ones.
Pages that already have hub content but were being swallowed by a fallback:
/galaxy/data-policy -> /eu/storage/ (content/eu/common/data-policy.md is an
include fragment; the hub publishes it
under /eu/storage/)
/people -> /eu/people/
{7 subsites}/people -> /<sub>/people/
{7 subsites}/publications -> /<sub>/citations/ (renamed on the hub)
/freiburg/{projects,services}
/freiburg/jobs[/*] -> /careers/
/freiburg/jobs is the one URL where this map was worse than the status quo:
it 301s to a working page today, but the subsite fallback would have sent the
three job ads to the Freiburg home page.
/livestream, /livestream-plain and /wall/* have no hub equivalent and are
recorded explicitly so a later reader can see they were considered.
All 30 targets verified 200 live.
The SSH (Social Sciences and Humanities) front page has been ported to the hub at /bare/eu/usegalaxy/ssh/, so /index-ssh no longer needs the /eu/ fallback. All three forms (bare, .html, trailing slash) follow. /index-test keeps the /eu/ fallback and is now commented as an intentional retirement: it was a throwaway test-server page and has no hub counterpart by decision, so the fallback is permanent rather than a gap awaiting a migration. Refs usegalaxy-eu/issues#943.
| # /feed.xml was jekyll-feed's site-wide posts feed; /eu/feed.atom is the hub | ||
| # equivalent. RSS -> Atom is a format change, but every mainstream reader | ||
| # follows the 301 and parses Atom. | ||
| location ~* "^/feed\.xml$" { |
There was a problem hiding this comment.
does that really exist? https://usegalaxy-eu.github.io/feed.xml ?
|
|
||
| # The rest should continue to be served by the European website, but under the github.io domain. | ||
| return 301 https://usegalaxy-eu.github.io$request_uri; | ||
| # No hub equivalent exists for these; recorded explicitly so that a future |
| location ~* "^/livestream(?:-plain)?(?:\.html|/)?$" { | ||
| return 301 https://galaxyproject.org/eu/; | ||
| } | ||
| location ~* "^/wall(?:/.*)?$" { |
There was a problem hiding this comment.
drop for now and ask @wm75 we should have a mastodon wall on the Hub already.
There was a problem hiding this comment.
Yes, there is https://galaxyproject.org/wall/ already - we just have to decide how much of this we want to host ourselves. Currently, https://gxy.io/fediwall points to fediwall.social passing it the config file at https://raw.githubusercontent.com/bgruening/fediwall-config/refs/heads/main/fediwall-config.json as a param.
I guess we could decide to:
- host just that config file
- host a fediwall instance (https://github.com/defnull/fediwall; static site) and its config file ourselves
If this takes some time to decide, we could just put a redirect to https://gxy.io/fediwall here for now.
There was a problem hiding this comment.
Thanks @wm75
@itisAliRH please redirect this one then to https://galaxyproject.org/wall/ for the time being.
| return 301 https://galaxyproject.org/eu/; | ||
| } | ||
|
|
||
| # --------------------------------------------------------------------------- |
There was a problem hiding this comment.
I think we should remove that and keep the config small.
We made sure that the posts / events are redirected on the Hub website. And if we add as a last resort fallback to the old jekyll website a info page (this website has migrated, please visit ...) that should be fine.
| location = /event/2022-10-28-analysis-data-Galaxy/ { return 301 https://galaxyproject.org/events/2022-10-psu-workshop/; } | ||
| location = /event/2022-10-28-community-call/ { return 301 https://galaxyproject.org/events/2022-11-17-community-call/; } | ||
| location = /event/2022-10-28-single-cell-RNA-seq/ { return 301 https://galaxyproject.org/events/2023-02-ebi-single-cell/; } | ||
| location = /event/2022-10-31-Galaxy-biohackaton-Europe/ { return 301 https://galaxyproject.org/events/2022-11-bh2022/; } |
There was a problem hiding this comment.
drop everything until here, all posts and events
| location = /event/2022-10-28-single-cell-RNA-seq/ { return 301 https://galaxyproject.org/events/2023-02-ebi-single-cell/; } | ||
| location = /event/2022-10-31-Galaxy-biohackaton-Europe/ { return 301 https://galaxyproject.org/events/2022-11-bh2022/; } | ||
|
|
||
| # Static assets keep their path on the hub, so map the prefix straight across. |
| return 301 https://galaxyproject.org$request_uri; | ||
| } | ||
|
|
||
| # Blanket rules for content that was never migrated individually -- chiefly the |
| location ~* "^/posts/\d{4}/\d{2}/\d{2}/" { return 301 https://galaxyproject.org/news/; } | ||
| location ~* "^/event/" { return 301 https://galaxyproject.org/eu/events/; } | ||
|
|
||
| # Anything not matched above is legacy content with no hub equivalent. |
There was a problem hiding this comment.
I would drop this as well, or redirect to a speical site that is:
- nice looking
- Apologize that the link is not working
- redirecting users to news, events, storage etc ....
|
@itisAliRH this now needs a rebase. |
Replaces the blanket
galaxyproject.eu→usegalaxy-eu.github.ioshim with a per-URL 301 map ontogalaxyproject.org, derived from the migration audit manifest and verified URL-by-URL against the live hub.master's config currently ends with:So today the entire legacy long tail is served by the GitHub Pages build of
usegalaxy-eu/website— the very repo that is slated for archival. This branch removes bothgithub.ioreferences (0 remain).Deploying this map is therefore a precondition for archiving
usegalaxy-eu/website, not a follow-up to it. Archiving that repo first would break every legacy URL, including the ~222 tool-update posts and every asset. This ordering constraint was not previously recorded anywhere in the migration work.Rule counts
location =location ~location ^~rewriteExact blocks: 663 news posts + 302 events + 4 structural.
Coverage
Posts and events (1187 published legacy URLs)
full(specific rule + hub content + live 200)redirect-only(blanket index)broken-targetno-ruleThe remaining 222 are exactly the auto-generated
tool-updateposts, collapsed to/news/by design (galaxyproject/galaxy-hub/issues/1480). Every other post and event now resolves to its own article.Pages, subdomains, subsites, feeds, assets (615 legacy URLs)
fullredirect-onlyno-rulebroken-targethonest-404(asset absent from hub, deliberate)Slashless URL normalisation — the largest defect fixed here
Every exact block is keyed on a trailing-slash URL, but the legacy host also answers the slashless form (GitHub Pages 301s
/posts/2018/10/08/gxadmin→/posts/2018/10/08/gxadmin/), so slashless URLs are real, linked and working in the wild. Without normalisation they matched no exact block and fell through to the blanket index — silently bypassing theentire rule table.
Measured by replaying all 1187 post/event URLs in slashless and
.htmlform against a real nginx running each config:.htmlvariant requests (2374)The 444 remaining are exactly 2 × the 222 tool-update posts.
What changed
migratedand the hub content exists and serves 200, but no rule was ever generated, so they landed on the index. Three manifest targets were mis-cased and 404 as recorded (/events/2022-11-BH2022/,/events/2022-10-PSU-Workshop/); the hub lower-cases published slugs, so all targets are written lower-cased and were re-verified live..htmlnormalisation — two server-level rewrites folding both forms onto the canonical key, following the existing plain/ICS folding pattern.[^/]+?cannot match a trailing slash, so no rewrite loop is possible.index-*bare forms./index-microbiome,/index-sshand/index-testwere keyed only on.htmland trailing slash, so the canonical bare form hit the generic rule and 404ed — all three werebroken-target. ** Six exact blocks (two of them dead) are replaced by three regex blocks covering all forms.index-microbiome.mdis a symlink toindex-metagenomics.mdin the legacy repo, andcontent/redirects.yamlin the hub independently declares the same target, so it now points at/bare/eu/usegalaxy/metagenomics/./assets/pass-through. All 467 legacy asset URLs previously hit the catch-all and 301ed to/eu/, answering an image request with a 52 KB HTML page at HTTP 200 — strictly worse than a 404, because nothing can detect the breakage. 163 exist on the hub at the identical path and are now recovered; the rest 404 honestly.The asset decision
css/,fonts/andjs/are deliberately included rather than carved out. None of them exist on the hub (it ships its own theme chrome), so they will 404 — but a 301 that ends in a 404 is a truthful answer, whereas the catch-all returns200 text/htmlfor a stylesheet request. A carve-out would add rules to produce a strictly worse outcome.Feeds
These are live subscriber endpoints, so a 301 to an HTML page breaks every reader silently.
/feed.xml/eu/feed.atom/events-ical/eu/events/calendar.icstext/html, so strict clients never worked; the hub serves realtext/calendar. Matchescontent/redirects.yaml./event/<slug>/event.icskeeps folding to its event page rather than to the EU calendar: that calendar contains only the 12 upcoming events, so a request for a 2022 event would import unrelated ones.Known gaps
These are deliberate and verified, not oversights.
/news/. Auto-generated changelog posts, collapsed by design (Hub unification: Initial launch checklist galaxyproject/galaxy-hub#1480).media/images + 10css/, 9fonts/, 4js/). These now 404 honestly instead of returning an HTML page at 200. Recovering them requires migrating the files, not a redirect change./index-sshand/index-testhave no hub counterpart →/eu/.index-sshis stranger than it looks: it returns 200 on the deployed legacy site but does not exist in the source tree at all — the deployed GitHub Pages branch carries files absent frommaster. Worth a separate look, since other deployed-only files may exist that neither a source derivation nor a crawl can see./<sub>/galaxy/,/<sub>/galaxy/gxnews,/<sub>/galaxy/gxeventsfor 6 subsites, plus/freiburg/maintenance/) → the subsite home./bare/<sub>/news/and/bare/<sub>/events/were probed and 404 on the hub; there is nothing to point at./livestream,/livestream-plain,/wall/,/wall/social_template→/eu/. No hub equivalent. Given explicit rules anyway so a future reader can see they were considered rather than missed./error_pages/*stay on the catch-all — infrastructure, not user-facing./_bibliography/*.bibneed no rule: an underscore directory Jekyll never published (404 on legacy today). The source data was migrated tocontent/*/citations/*.bib.Validation
nginx -tpasses on the rendered config..htmlvariants replayed through a real nginx: 0 disagreements with the canonical form.Note for reviewing on macOS
nginx -tfails locally on macOS withduplicate location "/event/2022-07-05-community-call/". This is a platform artifact, not a config defect: nginx definesNGX_HAVE_CASELESS_FILESYSTEMon Darwin and Win32, songx_filename_cmpcompares location keys case-insensitively there. Linux — the deploy target — is case-sensitive._events/2022-07-05-Community-Call.mdand_events/2022-07-05-community-call.mdare two distinct source files with distinct content, both live 200 on the legacy site, mapping to two different hub events. Both rules are required. Verified: 0 duplicates under case-sensitive (Linux) semantics.