Conversation
abbfa0f to
fd2f7c0
Compare
fd2f7c0 to
689de4f
Compare
61da780 to
2ceb3f5
Compare
2ceb3f5 to
57fe298
Compare
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
| <link rel="apple-touch-icon" href="apple-touch-icon.png" /> | ||
| <base > | ||
| <base href="../../" /> |
There was a problem hiding this comment.
here i wouldn't recommend to change the base url but modify all other calls, as this might be problematic for any other calls
so i would put ../../ before any other scr
../../config?autoload=1
../../static/js/i18n.js
../../i18ncatalog?autoload=1
../../static/app/Splunk_TA_UCCExample/js/build/entry_page.js
it should still work but it wont modify any other calls that are there.
There was a problem hiding this comment.
Good catch — you're right that <base href> affects all relative references on the page, not just the ones we control. Switched to explicit ../../ prefixes on each src attribute instead. The change was straightforward since this approach was already validated in an earlier iteration of this PR (commit 689de4f).
| <base href="../../" /> | ||
| <script src="config?autoload=1" crossorigin="use-credentials"></script> | ||
| <script src="static/js/i18n.js"></script> | ||
| <script src="i18ncatalog?autoload=1"></script> |
There was a problem hiding this comment.
pointing it out to make sure to test it,
here is a slight behaviour change regarding Splunk caching mechanism
before:
every app pointed to (hash changed from time to time):
http://localhost:8000/en-GB/static/@4D5115C2BBEDBE564FA527CC44093F940E617B8AF35782CBC9A44889DB0D66FB.83/js/i18n.js
now every app fetches
http://localhost:8000/en-GB/static/js/i18n.js
after a brief AI questions about differences:
whats the difference between those 2 links:
The difference between these two URLs is the cache-busting hash in the second URL:
http://localhost:8000/en-GB/static/js/i18n.js
Direct path to the static file
No versioning or cache control
http://localhost:8000/en-GB/static/@4D5115C2BBEDBE564FA527CC44093F940E617B8AF35782CBC9A44889DB0D66FB.83/js/i18n.js
Contains a hash: @4D5115C2BBEDBE564FA527CC44093F940E617B8AF35782CBC9A44889DB0D66FB.83
This is a content hash or build hash used for cache busting
Why Splunk uses the hash:
Cache Busting: When the file content changes, the hash changes, forcing browsers to download the new version instead of using cached content
Long-term Caching: Splunk can set aggressive cache headers (cache forever) because the URL will change when content changes
Version Control: The .83 might indicate a Splunk version number
Performance: Browsers can safely cache these files indefinitely without worrying about stale content
How it works:
Both URLs serve the same file, but Splunk's web server (typically Splunkd or Cherrypy) intercepts requests with the @HASH pattern and strips it out before serving the actual file. The hash itself doesn't correspond to a real directory—it's middleware that handles the routing.
This is a common pattern in modern web applications (similar to webpack's [contenthash] or other build tools) to ensure optimal caching while preventing stale resources.
what is the problem if i will be using the version without hashes
If you use the version without hashes, you'll face several potential problems:
1. Browser Caching Issues (Most Critical)
Stale Content: Browsers will cache i18n.js and may not fetch the updated version even after you deploy changes
User Experience: Users might see old UI behavior, broken functionality, or outdated translations
Hard Refresh Required: Users would need to manually clear cache or do hard refresh (Ctrl+F5) to see updates
2. Version Mismatch Problems
Mixed Versions: If your HTML updates but cached JS doesn't, you can get:
JavaScript errors
Missing functions/methods
Broken API calls
UI rendering issues
3. Splunk-Specific Issues
App Updates: When you upgrade your Splunk app, users might continue using old JavaScript files
Configuration Changes: If your globalConfig.json or other configs change, the old JS might not handle them correctly
Development Pain: During development, you'll constantly fight browser cache
4. Cache Control Challenges
Without hashes, you'd need to:
Set short cache expiration times (slower page loads)
OR risk serving stale content (broken functionality)
No good middle ground
Workarounds (if you can't use hashes):
<!-- Query string versioning -->
<script src="/static/js/i18n.js?v=1.2.3"></script>
<!-- Timestamp -->
<script src="/static/js/i18n.js?t=1234567890"></script>
<!-- App version -->
<script src="/static/js/i18n.js?v=${app_version}"></script>
But these are inferior to content hashing because:
Version bumps happen even if the file didn't change
Requires manual version management
Less reliable than content-based hashing
Bottom line: The hash ensures users always get the correct version of your JavaScript that matches your current app deployment. It's a best practice for production web applications.
if i wont use hashes how will the upgrade Splunk Enterprise itself (e.g., 8.2 → 8.3 → 9.0) loook like from the file i18.js perspective
Scenario: Upgrading Splunk 8.2 → 9.0
WITH Hashes (Normal Splunk behavior):
Before upgrade (Splunk 8.2):
http://localhost:8000/en-GB/static/@HASH82.82/js/i18n.js
↓
Splunk 8.2 upgraded to 9.0
↓
After upgrade (Splunk 9.0):
http://localhost:8000/en-GB/static/@HASH90.90/js/i18n.js
What happens:
User visits app after upgrade
Browser sees new URL with different hash
Browser: "Oh, this is a NEW file" → downloads fresh version
✅ User gets Splunk 9.0's updated i18n.js immediately
WITHOUT Hashes (Your scenario):
Before upgrade (Splunk 8.2):
http://localhost:8000/en-GB/static/js/i18n.js
↓
Splunk 8.2 upgraded to 9.0
↓
After upgrade (Splunk 9.0):
http://localhost:8000/en-GB/static/js/i18n.js (SAME URL!)
What happens:
User visits app after upgrade
Browser sees exact same URL
Browser: "I have this file cached" → uses OLD Splunk 8.2 version
❌ User still runs Splunk 8.2 JavaScript on Splunk 9.0 backend
The Problems This Causes:
// Splunk 9.0 i18n.js (on server, but NOT loaded)
i18n.newSplunk9Feature = function() { ... }
// Splunk 8.2 i18n.js (cached in browser, STILL RUNNING)
// Missing: newSplunk9Feature
// Your app tries to call:
i18n.newSplunk9Feature();
// ❌ TypeError: i18n.newSplunk9Feature is not a function
Real-World Impact:
Broken Functionality
New Splunk 9.0 features don't work
API calls fail (backend expects 9.0 format, JS sends 8.2 format)
UI Rendering Issues
<!-- Splunk 9.0 HTML expects new JS classes -->
<div class="splunk-9-new-component"></div>
<!-- But cached 8.2 JS doesn't know how to render it -->
Silent Failures
Errors in browser console
Features appear "broken"
User thinks upgrade failed
How Long Does Cache Persist?
Depends on cache headers. If Splunk set:
Cache-Control: max-age=31536000 (1 year!)
Without hash change, browser will not check for updates for up to 1 year! User would need to:
Hard refresh (Ctrl+F5)
Clear browser cache manually
Wait for cache expiration
There was a problem hiding this comment.
Valid observation. The hash-based URLs (e.g. @4D5115C2....83/js/i18n.js) were generated dynamically by Splunk's make_url() at render time via CherryPy/Mako — we were just a pass-through. Reproducing that mechanism without a runtime isn't feasible: the hash is computed by Splunk at startup from its own file contents, and we don't have access to it at ucc-gen build time.
The two endpoints with ?autoload=1 (config and i18ncatalog) are inherently dynamic and session-scoped, so they aren't aggressively cached by browsers regardless — the cache busting concern doesn't apply to them.
For i18n.js specifically, the actual cache behavior depends on what Cache-Control headers Splunk sets for unhashed static paths — which we haven't verified. We plan to check this against a running Splunk instance using run_splunk.sh and will follow up with results. If the headers turn out to be permissive, we'll document this as a known limitation of removing the Mako runtime dependency.
There was a problem hiding this comment.
What if ucc-gen build added some random hash? Or SHA of the js file? This way the hash would be different after TA upgrade.
There was a problem hiding this comment.
Good catch — I verified that /static/js/i18n.js is served with Cache-Control: public, max-age=31536000, so the concern from the earlier comment was valid.
Why a random hash or SHA won't work here:
- Random hash: would change on every
ucc-gen build, busting the cache on every TA upgrade. Buti18n.jsis a Splunk file — its content only changes when Splunk itself upgrades. Busting on every TA build would be the wrong signal. - SHA of the file:
i18n.jsis dynamically generated per-locale by Splunk's CherryPy at request time (seedispatch_i18n_js()in Splunk'si18n.py). We don't have access to its final content atucc-gen buildtime, so we can't compute a meaningful SHA.
What we did instead:
config?autoload=1 (already loaded synchronously in <head>) populates window.$C, which includes BUILD_NUMBER — a value that changes on every Splunk upgrade. We use it to build the URL dynamically at page load:
var _b = window.$C && window.$C.BUILD_NUMBER ? '/@' + window.$C.BUILD_NUMBER : '';
_loadScript('../../static' + _b + '/js/i18n.js')This produces URLs like ../../static/@389585/js/i18n.js. Splunk's customstaticdir.py strips any /@ANYTHING segment before serving the file, so the path resolves correctly regardless of the value. The cache is busted exactly when Splunk upgrades — which is when i18n.js content actually changes.
149e136 to
7a0a17a
Compare
5151d97 to
fd60793
Compare
Code Coverage 🎉
|
Issue number:
ADDON-86196
PR Type
What kind of change does this PR introduce?
Summary
This PR removes Mako syntax and CherryPy-dependent runtime logic from the generated app templates used by UCC add-ons.
The original
base.htmlandredirect.htmltemplates relied on Mako constructs (<%! %>,<% %>,${...}) and oncherrypy.request.path_infoto resolve the app name and asset paths at render time. This caused AppInspect issues and made the templates depend on Splunk Web template execution details.After this change, the generated templates are plain HTML only. App-specific values are injected during build, and the Splunk bootstrap scripts are loaded through static relative paths so the UI still initializes correctly without any Mako expressions in the templates.
Changes
base.html<head>entry_page.jsthrough a static relative path with__APP_NAME__replaced during buildredirect.html<head>__APP_NAME__,__TA_NAME__, and__TA_VERSION__replaced during buildbuild.pypackage_files_update.pyTests / fixtures
User experience
Before:
After:
Checklist
If an item does not apply to your changes, leave it unchecked.
Review
Tests
See the testing doc.
Demo/meeting:
Reviewers are encouraged to request meetings or demos if any part of the change is unclear