| |
@@ -43,6 +43,9 @@
|
| |
"metal_virtualized": "metal-virtualized",
|
| |
"cloud_operators": "cloud-operators"
|
| |
}
|
| |
+ function isEmptyObj(obj) {
|
| |
+ return Object.entries(obj).length === 0 && obj.constructor === Object;
|
| |
+ }
|
| |
function getMember(obj, member) {
|
| |
return (member in obj) ? obj[member] : null;
|
| |
}
|
| |
@@ -94,6 +97,8 @@
|
| |
streamUrl: "",
|
| |
// fetched {stream, metadata, architectures, updates} object from stream.json
|
| |
streamData: null,
|
| |
+ // fetched {stream, metadata, architectures, updates} object from stream.json for all streams
|
| |
+ streamDataAll: { stable: {}, testing: {}, next: {} },
|
| |
loading: false,
|
| |
// loaded stream data to render
|
| |
streamDisplay: {
|
| |
@@ -103,9 +108,48 @@
|
| |
cloud: {}
|
| |
},
|
| |
},
|
| |
- watch: { stream: function() {
|
| |
- this.refreshStream();
|
| |
- } },
|
| |
+ watch: {
|
| |
+ stream: function() {
|
| |
+ this.refreshStream();
|
| |
+ },
|
| |
+ // watching nested data: https://stackoverflow.com/a/46331968
|
| |
+ "streamDataAll.stable": function(newVal, oldVal) {
|
| |
+ if (isEmptyObj(this.streamDataAll.stable)) {
|
| |
+ return
|
| |
+ }
|
| |
+
|
| |
+ stableReleaseVersion = "v " + this.streamDataAll.stable.architectures.x86_64.artifacts.metal.release;
|
| |
+ $("#stable-version").text(stableReleaseVersion);
|
| |
+
|
| |
+ $("#stable-json").empty();
|
| |
+ $("#stable-json").append(`<a class="text-gray-600" href="${baseUrl}/stable.json">JSON</a>`);
|
| |
+ $("#stable-json").append(` — <span>${this.timeSince(this.streamDataAll.stable.metadata['last-modified'])}</span>`);
|
| |
+ },
|
| |
+ "streamDataAll.testing": function(newVal, oldVal) {
|
| |
+ if (isEmptyObj(this.streamDataAll.testing)) {
|
| |
+ return
|
| |
+ }
|
| |
+
|
| |
+ testingReleaseVersion = isEmptyObj(this.streamDataAll.testing) ? "" : "v " + this.streamDataAll.testing.architectures.x86_64.artifacts.metal.release;
|
| |
+ $("#testing-version").text(testingReleaseVersion);
|
| |
+
|
| |
+ $("#testing-json").empty();
|
| |
+ $("#testing-json").append(`<a class="text-gray-600" href="${baseUrl}/testing.json">JSON</a>`);
|
| |
+ $("#testing-json").append(` — <span>${this.timeSince(this.streamDataAll.testing.metadata['last-modified'])}</span>`);
|
| |
+ },
|
| |
+ "streamDataAll.next": function(newVal, oldVal) {
|
| |
+ if (isEmptyObj(this.streamDataAll.next)) {
|
| |
+ return
|
| |
+ }
|
| |
+
|
| |
+ nextReleaseVersion = isEmptyObj(this.streamDataAll.next) ? "" : "v " + this.streamDataAll.next.architectures.x86_64.artifacts.metal.release;
|
| |
+ $("#next-version").text(nextReleaseVersion);
|
| |
+
|
| |
+ $("#next-json").empty();
|
| |
+ $("#next-json").append(`<a class="text-gray-600" href="${baseUrl}/next.json">JSON</a>`);
|
| |
+ $("#next-json").append(` — <span>${this.timeSince(this.streamDataAll.next.metadata['last-modified'])}</span>`);
|
| |
+ }
|
| |
+ },
|
| |
methods: {
|
| |
getObjectUrl: function(path) {
|
| |
return getArtifactUrl(this.streamUrl, path);
|
| |
@@ -137,70 +181,196 @@
|
| |
return stringize(Math.floor(elapsed/msPerYear), "year");
|
| |
}
|
| |
},
|
| |
+ // Callback function for the navigation bar
|
| |
+ // Effects:
|
| |
+ // - hides the other tabs other than the clicked one
|
| |
+ // - replace the current URL parameter with the clicked one
|
| |
toggleHidden: function(e) {
|
| |
- const id_list = Object.values(IdPool);
|
| |
+ const idList = Object.values(IdPool);
|
| |
Object.entries(tabInnerText).map(pair => {
|
| |
const key = pair[0];
|
| |
const val = pair[1];
|
| |
if (val === e.target.innerText) {
|
| |
const downloadPageUrl = window.location.href.match(/^.*\/coreos\/download/)[0];
|
| |
- history.pushState(null, null, `${downloadPageUrl}?tab=${key}&stream=${coreos_download_app.stream}`);
|
| |
- const show_id = IdPool[key];
|
| |
- id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
- this.shownId = show_id;
|
| |
+ history.replaceState(null, null, `${downloadPageUrl}?tab=${key}&stream=${coreos_download_app.stream}`);
|
| |
+ const showId = IdPool[key];
|
| |
+ idList.map(id => document.getElementById(id).hidden = (id !== showId));
|
| |
+ this.shownId = showId;
|
| |
}
|
| |
});
|
| |
},
|
| |
+ // Render a navbar section
|
| |
getNavbar: function(h) {
|
| |
- cloud_icon = h('i', { class: "fas fa-cloud mr-2" })
|
| |
- nav_cloud_launchable_btn = h('button', { class: "nav-link col-12 h-100 overflow-hidden".concat(this.shownId === IdPool.cloud_launchable ? " active" : ""), attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ cloud_icon, tabInnerText.cloud_launchable ]);
|
| |
- nav_cloud_launchable = h('li', { class: "nav-item col-4" }, [ nav_cloud_launchable_btn ]);
|
| |
+ cloudIcon = h('i', { class: "fas fa-cloud mr-2" })
|
| |
+ navCloudLaunchableBtn = h('button', { class: "nav-link col-12 h-100 overflow-hidden".concat(this.shownId === IdPool.cloud_launchable ? " active" : ""), attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ cloudIcon, tabInnerText.cloud_launchable ]);
|
| |
+ navCloudLaunchable = h('li', { class: "nav-item col-12 col-sm-4" }, [ navCloudLaunchableBtn ]);
|
| |
|
| |
- server_icon = h('i', { class: "fas fa-server mr-2" })
|
| |
- nav_metal_virt_btn = h('button', { class: "nav-link col-12 h-100 overflow-hidden".concat(this.shownId === IdPool.metal_virtualized ? " active" : ""), attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ server_icon, tabInnerText.metal_virtualized ]);
|
| |
- nav_metal_virt = h('li', { class: "nav-item col-4" }, [ nav_metal_virt_btn ]);
|
| |
+ serverIcon = h('i', { class: "fas fa-server mr-2" })
|
| |
+ navMetalVirtBtn = h('button', { class: "nav-link col-12 h-100 overflow-hidden".concat(this.shownId === IdPool.metal_virtualized ? " active" : ""), attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ serverIcon, tabInnerText.metal_virtualized ]);
|
| |
+ navMetalVirt = h('li', { class: "nav-item col-12 col-sm-4" }, [ navMetalVirtBtn ]);
|
| |
|
| |
- cloud_upload_icon = h('i', { class: "fas fa-cloud-upload-alt mr-2" })
|
| |
- nav_cloud_operators_btn = h('button', { class: "nav-link col-12 h-100 overflow-hidden".concat(this.shownId === IdPool.cloud_operators ? " active" : ""), attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ cloud_upload_icon, tabInnerText.cloud_operators ]);
|
| |
- nav_cloud_operators = h('li', { class: "nav-item col-4" }, [ nav_cloud_operators_btn ]);
|
| |
+ cloudUploadIcon = h('i', { class: "fas fa-cloud-upload-alt mr-2" })
|
| |
+ navCloudOperatorsBtn = h('button', { class: "nav-link col-12 h-100 overflow-hidden".concat(this.shownId === IdPool.cloud_operators ? " active" : ""), attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ cloudUploadIcon, tabInnerText.cloud_operators ]);
|
| |
+ navCloudOperators = h('li', { class: "nav-item col-12 col-sm-4" }, [ navCloudOperatorsBtn ]);
|
| |
|
| |
- navbar = h('ul', { class: "nav nav-tabs" }, [ nav_cloud_launchable, nav_metal_virt, nav_cloud_operators ]);
|
| |
+ navbar = h('ul', { class: "nav nav-tabs" }, [ navCloudLaunchable, navMetalVirt, navCloudOperators ]);
|
| |
return navbar;
|
| |
},
|
| |
- // Add dropdown options of streams
|
| |
+ // Render a dropdown list with options of streams
|
| |
getStreamName: function(h) {
|
| |
const self = this;
|
| |
if (this.streamData === null) return;
|
| |
- option_stable = h('option', { attrs: { value: "stable", selected: this.stream === "stable" ? "selected" : null }}, "stable");
|
| |
- option_testing = h('option', { attrs: { value: "testing", selected: this.stream === "testing" ? "selected" : null }}, "testing");
|
| |
- option_next = h('option', { attrs: { value: "next", selected: this.stream === "next" ? "selected" : null }}, "next");
|
| |
- selectOptions = h('select', {
|
| |
- class: "mx-1",
|
| |
+
|
| |
+ function onClick(e) {
|
| |
+ const downloadPageUrl = window.location.href.match(/^.*\/coreos\/download/)[0];
|
| |
+ const currentShownKey = Object.keys(IdPool).find(key => IdPool[key] === self.shownId);
|
| |
+ coreos_download_app.stream = e.target.value;
|
| |
+ history.replaceState(null, null, `${downloadPageUrl}?tab=${currentShownKey}&stream=${coreos_download_app.stream}`);
|
| |
+ }
|
| |
+
|
| |
+ btnDropdownToggle = h('button', { class: "btn btn-sm bg-gray-200 dropdown-toggle py-0", attrs: { type: "button", id: "dropdownMenuStreams", "data-toggle": "dropdown", "aria-haspopup": true, "aria-expanded": false } }, self.stream );
|
| |
+ btnDropdownStable = h('button', { class: "dropdown-item", attrs: { type: "button", value: "stable" }, on: { click: onClick } }, "stable");
|
| |
+ btnDropdownTesting = h('button', { class: "dropdown-item", attrs: { type: "button", value: "testing" }, on: { click: onClick } }, "testing");
|
| |
+ btnDropdownNext = h('button', { class: "dropdown-item", attrs: { type: "button", value: "next" }, on: { click: onClick } }, "next");
|
| |
+ divDropdownMenu = h('div', { class: "dropdown-menu", attrs: { "aria-labelledby": "dropdownMenuStreams" } }, [ btnDropdownStable, btnDropdownTesting, btnDropdownNext ]);
|
| |
+ divDropdown = h('div', { class: "d-inline dropdown ml-2" }, [ btnDropdownToggle, divDropdownMenu ])
|
| |
+
|
| |
+ streamName = h('p', { class: "mt-5 mb-2 ml-3" }, [
|
| |
+ "Currently Selected Stream:",
|
| |
+ divDropdown ]);
|
| |
+ return streamName;
|
| |
+ },
|
| |
+ // Introduction section for streams, the section above the navigation bar for platforms
|
| |
+ getStreamIntro: function(h) {
|
| |
+ const overviewPageUrl = window.location.href.match(/^.*\/coreos/)[0];
|
| |
+ title = h('h2', { class: "font-weight-light text-center pb-3 mb-3" }, "Fedora CoreOS is available across 3 different release streams:");
|
| |
+
|
| |
+ if (this.loading) {
|
| |
+ return title;
|
| |
+ }
|
| |
+
|
| |
+ viewAllStreamsBtn = h('button',
|
| |
+ {
|
| |
+ class: "d-block mx-auto mb-5 py-1 btn btn-sm btn-fedora-purple",
|
| |
+ on: {
|
| |
+ click: function(e) {
|
| |
+ e.preventDefault();
|
| |
+ window.open(`${overviewPageUrl}`);
|
| |
+ }
|
| |
+ }
|
| |
+ }, "View All Streams");
|
| |
+
|
| |
+ // Release info section with three tabs: stable, testing, next
|
| |
+ // NOTE: in order for the button line up at the same horizontal level, use a fixed height `9em` for <p> elements of stream summaries.
|
| |
+ stableIcon = h("i", {
|
| |
+ class: "fas fa-shield-alt fa-2x rounded-circle bg-fedora-blue text-white p-3 ml-4",
|
| |
+ }, "");
|
| |
+ stableHeading = h("h3", { class: "font-weight-light" }, "Stable");
|
| |
+ stableReleaseVersion = h("h6", { class: "text-gray-500 mb-0", attrs: { id: "stable-version" }}, isEmptyObj(this.streamDataAll.stable) ? "" : "v " + this.streamDataAll.stable.architectures.x86_64.artifacts.metal.release);
|
| |
+ stableJSON = h('p', { class: "text-gray-500", attrs: { id: "stable-json" } }, [
|
| |
+ h('span', {}, [
|
| |
+ h('a', { class: "font-weight-bold text-gray-500", attrs: { href: `${baseUrl}/stable.json` } }, "JSON")
|
| |
+ ]),
|
| |
+ (isEmptyObj(this.streamDataAll.stable)) ? null : " — ",
|
| |
+ (isEmptyObj(this.streamDataAll.stable)) ? null : h('span', { class: "font-weight-normal" }, this.timeSince(this.streamDataAll.stable.metadata['last-modified']))
|
| |
+ ]);
|
| |
+ stableIconContainer = h("div", { class: "col-4" }, [ stableIcon ])
|
| |
+ stableReleaseJSONContainer = h("div", { class: "col-8" }, [ stableHeading, stableReleaseVersion, stableJSON ])
|
| |
+ stableHeadingContainer = h("div", { class: "row" }, [ stableIconContainer, stableReleaseJSONContainer ])
|
| |
+
|
| |
+ stableIntroText = h("p", { class: "pl-3 pr-2", style: { height: "9em" } }, "The Stable Stream should be used by production clusters. Versions of Fedora CoreOS are battle-tested within the Testing and Next streams before being promoted.");
|
| |
+ stableReleaseLink = h('button',
|
| |
+ {
|
| |
+ class: "d-block mx-auto mb-4 py-1 btn btn-sm btn-fedora-blue",
|
| |
on: {
|
| |
- change: function(e) {
|
| |
- const downloadPageUrl = window.location.href.match(/^.*\/coreos\/download/)[0];
|
| |
- const currentShownKey = Object.keys(IdPool).find(key => IdPool[key] === self.shownId);
|
| |
- coreos_download_app.stream = e.target.value;
|
| |
- history.pushState(null, null, `${downloadPageUrl}?tab=${currentShownKey}&stream=${coreos_download_app.stream}`);
|
| |
+ click: function(e) {
|
| |
+ e.preventDefault();
|
| |
+ window.open(`${overviewPageUrl}?stream=stable`);
|
| |
}
|
| |
}
|
| |
- }, [
|
| |
- option_stable,
|
| |
- option_testing,
|
| |
- option_next
|
| |
+ }, "View Stable Releases");
|
| |
+
|
| |
+ // then Testing stream
|
| |
+ testingIcon = h("i", {
|
| |
+ class: "fas fa-flask fa-2x rounded-circle bg-fedora-green text-white p-3 ml-4",
|
| |
+ }, "");
|
| |
+ testingHeading = h("h3", { class: "font-weight-light" }, "Testing");
|
| |
+ testingReleaseVersion = h("h6", { class: "text-gray-500 mb-0", attrs: { id: "testing-version" }}, isEmptyObj(this.streamDataAll.testing) ? "" : "v " + this.streamDataAll.testing.architectures.x86_64.artifacts.metal.release);
|
| |
+ testingJSON = h('p', { class: "text-gray-500", attrs: { id: "testing-json" } }, [
|
| |
+ h('span', {}, [
|
| |
+ h('a', { class: "font-weight-bold text-gray-500", attrs: { href: `${baseUrl}/testing.json` } }, "JSON")
|
| |
+ ]),
|
| |
+ (isEmptyObj(this.streamDataAll.testing)) ? null : " — ",
|
| |
+ (isEmptyObj(this.streamDataAll.testing)) ? null : h('span', { class: "font-weight-normal" }, this.timeSince(this.streamDataAll.testing.metadata['last-modified']))
|
| |
]);
|
| |
- streamName = h('p', {}, [
|
| |
- "Stream: ",
|
| |
- selectOptions,
|
| |
- " (",
|
| |
+ testingIconContainer = h("div", { class: "col-4" }, [ testingIcon ])
|
| |
+ testingReleaseJSONContainer = h("div", { class: "col-8" }, [ testingHeading, testingReleaseVersion, testingJSON ])
|
| |
+ testingHeadingContainer = h("div", { class: "row" }, [ testingIconContainer, testingReleaseJSONContainer ])
|
| |
+
|
| |
+ testingIntroText = h("p", { class: "pl-3 pr-2", style: { height: "9em" } }, "The Testing stream consists of promoted Next releases. Mix a few Testing machines into your production clusters to catch any bugs specific to your hardware or configuration.");
|
| |
+ testingReleaseLink = h('button',
|
| |
+ {
|
| |
+ class: "d-block mx-auto mb-4 py-1 btn btn-sm btn-fedora-green",
|
| |
+ on: {
|
| |
+ click: function(e) {
|
| |
+ e.preventDefault();
|
| |
+ window.open(`${overviewPageUrl}?stream=testing`);
|
| |
+ }
|
| |
+ }
|
| |
+ }, "View Testing Releases");
|
| |
+
|
| |
+ // then Next stream
|
| |
+ nextIcon = h("i", {
|
| |
+ class: "fas fa-layer-group fa-2x rounded-circle bg-fedora-orange text-white p-3 ml-4",
|
| |
+ }, "");
|
| |
+ nextHeading = h("h3", { class: "font-weight-light" }, "Next");
|
| |
+ nextReleaseVersion = h("h6", { class: "text-gray-500 mb-0", attrs: { id: "next-version" }}, isEmptyObj(this.streamDataAll.next) ? "" : "v " + this.streamDataAll.next.architectures.x86_64.artifacts.metal.release);
|
| |
+ nextJSON = h('p', { class: "text-gray-500", attrs: { id: "next-json" } }, [
|
| |
h('span', {}, [
|
| |
- h('a', { attrs: { href: this.getObjectUrl(this.stream + '.json') } }, "JSON")
|
| |
+ h('a', { class: "font-weight-bold text-gray-500", attrs: { href: `${baseUrl}/next.json` } }, "JSON")
|
| |
]),
|
| |
- ")",
|
| |
- (this.streamData.metadata) ? "—" : null,
|
| |
- (this.streamData.metadata) ? h('span', {}, this.timeSince(this.streamData.metadata['last-modified'])) : null
|
| |
+ (isEmptyObj(this.streamDataAll.next)) ? null : " — ",
|
| |
+ (isEmptyObj(this.streamDataAll.next)) ? null : h('span', { class: "font-weight-normal" }, this.timeSince(this.streamDataAll.next.metadata['last-modified']))
|
| |
]);
|
| |
- return streamName;
|
| |
+ nextIconContainer = h("div", { class: "col-4" }, [ nextIcon ])
|
| |
+ nextReleaseJSONContainer = h("div", { class: "col-8" }, [ nextHeading, nextReleaseVersion, nextJSON ])
|
| |
+ nextHeadingContainer = h("div", { class: "row" }, [ nextIconContainer, nextReleaseJSONContainer ])
|
| |
+
|
| |
+
|
| |
+ nextIntroText = h("p", { class: "pl-3 pr-2", style: { height: "9em" } }, "The Next stream closely tracks current development work and is released frequently. The newest versions of the Linux kernel, Systemd, and other components will be available for testing.");
|
| |
+ nextReleaseLink = h('button',
|
| |
+ {
|
| |
+ class: "d-block mx-auto mb-4 py-1 btn btn-sm btn-fedora-orange",
|
| |
+ on: {
|
| |
+ click: function(e) {
|
| |
+ e.preventDefault();
|
| |
+ window.open(`${overviewPageUrl}?stream=next`);
|
| |
+ }
|
| |
+ }
|
| |
+ }, "View Next Releases");
|
| |
+
|
| |
+ stableDiv = h('div', {
|
| |
+ class: "col-12 col-lg-4 border-left border-fedora-blue pt-3",
|
| |
+ style: {
|
| |
+ "border-width": "10px !important",
|
| |
+ }
|
| |
+ }, [stableHeadingContainer, stableIntroText, stableReleaseLink])
|
| |
+ testingDiv = h('div', {
|
| |
+ class: "col-12 col-lg-4 border-left border-fedora-green pt-3",
|
| |
+ style: {
|
| |
+ "border-width": "10px !important",
|
| |
+ }
|
| |
+ }, [testingHeadingContainer, testingIntroText, testingReleaseLink])
|
| |
+ nextDiv = h('div', {
|
| |
+ class: "col-12 col-lg-4 border-left border-fedora-orange pt-3",
|
| |
+ style: {
|
| |
+ "border-width": "10px !important",
|
| |
+ }
|
| |
+ }, [nextHeadingContainer, nextIntroText, nextReleaseLink])
|
| |
+
|
| |
+ streamsIntroDiv = h('div', { class: "row my-3" }, [stableDiv, testingDiv, nextDiv]);
|
| |
+ wrapperDiv = h('div', {}, [title, viewAllStreamsBtn, streamsIntroDiv]);
|
| |
+ return wrapperDiv;
|
| |
},
|
| |
isAws: function(platform) {
|
| |
return platform == "aws";
|
| |
@@ -318,15 +488,32 @@
|
| |
}
|
| |
}
|
| |
},
|
| |
+ // Load all stream metadata for rendering
|
| |
refreshStream: function() {
|
| |
- this.loading = true
|
| |
- this.streamUrl = baseUrl
|
| |
- fetchStreamData(this.streamUrl, this.stream).then(streamData => {
|
| |
- this.loading = false;
|
| |
- this.streamData = Object.entries(streamData).length === 0 && streamData.constructor === Object ? null : streamData;
|
| |
- this.loadStreamDisplay();
|
| |
- });
|
| |
+ const self = this;
|
| |
+ self.loading = true
|
| |
+ self.streamUrl = baseUrl
|
| |
+ fetchStreamData(baseUrl, "stable")
|
| |
+ .then(streamData => {
|
| |
+ self.streamDataAll.stable = streamData;
|
| |
+ return fetchStreamData(baseUrl, "testing");
|
| |
+ })
|
| |
+ .then(streamData => {
|
| |
+ self.streamDataAll.testing = streamData;
|
| |
+ return fetchStreamData(baseUrl, "next");
|
| |
+ })
|
| |
+ .then(streamData => {
|
| |
+ self.streamDataAll.next = streamData;
|
| |
+ return;
|
| |
+ })
|
| |
+ .then(() =>{
|
| |
+ const streamData = self.streamDataAll[self.stream];
|
| |
+ self.loading = false;
|
| |
+ self.streamData = isEmptyObj(streamData) ? null : streamData;
|
| |
+ self.loadStreamDisplay();
|
| |
+ })
|
| |
},
|
| |
+ // Render the `Verify signature & SHA256` modal template
|
| |
getSignatureAndShaModal: function(h) {
|
| |
return h('div', { class: "modal", attrs: { id: "signatureAndShaModal", tabindex: "-1", role: "dialog", "aria-labelledby": "signatureAndShaModalLabel", "aria-hidden": "true" }}, [
|
| |
h('div', { class: "modal-dialog modal-lg modal-dialog-centered", attrs: { role: "document" }}, [
|
| |
@@ -351,6 +538,9 @@
|
| |
}
|
| |
},
|
| |
render: function(h) {
|
| |
+ if(window.location.href.match(/^.*\/coreos\/download/) == null) {
|
| |
+ return
|
| |
+ }
|
| |
const downloadPageUrl = window.location.href.match(/^.*\/coreos\/download/)[0];
|
| |
searchParams = new URLSearchParams(window.location.search);
|
| |
// switch to specified tab if `tab` parameter is set
|
| |
@@ -390,15 +580,17 @@
|
| |
searchParams.set('stream', 'stable');
|
| |
}
|
| |
// Update the url with the parameters
|
| |
- history.pushState(null, null, `${downloadPageUrl}?${searchParams.toString()}`);
|
| |
+ history.replaceState(null, null, `${downloadPageUrl}?${searchParams.toString()}`);
|
| |
|
| |
- var signature_sha256_verification_modal = this.getSignatureAndShaModal(h);
|
| |
- var stream_select_container = h('div', { class: "pb-0 pt-3 mb-3" }, [ h('div', { class: "container" }, [ this.getStreamName(h), this.getNavbar(h) ]) ]);
|
| |
+ var signatureSha256VerificationModal = this.getSignatureAndShaModal(h);
|
| |
+ h1Title = h('h1', { class: "font-weight-light text-center my-5" }, "Download Fedora CoreOS");
|
| |
+ streamSelectContainer = h('div', { class: "pb-0 pt-3 mb-3" }, [ this.getStreamIntro(h), this.getStreamName(h), this.getNavbar(h) ]);
|
| |
if (this.loading) {
|
| |
- return h('div', {}, [ stream_select_container, "Loading..."] );
|
| |
+ streamInfoDiv = h('div', { class: "bg-light pt-3" }, [ h('div', { class: "container font-weight-light" }, [ streamSelectContainer ]) ]);
|
| |
+ downloadDiv = h('div', { class: "bg-white pb-5" }, [ h('div', { class: "container font-weight-light" }, "Loading...") ]);
|
| |
+ return h('div', {}, [ h1Title, streamInfoDiv, downloadDiv ]);
|
| |
}
|
| |
else if (this.streamData) {
|
| |
- cloudLaunchableTitle = h('h3', { class:"font-weight-light" }, "Cloud Launchable");
|
| |
cloudLaunchableSection = {};
|
| |
cloudLaunchable = {};
|
| |
virtualizedTitle = h('h3', { class:"font-weight-light" }, "Virtualized");
|
| |
@@ -407,7 +599,6 @@
|
| |
bareMetalTitle = h('h3', { class:"font-weight-light" }, "Bare Metal");
|
| |
bareMetalSection = {};
|
| |
bareMetal = {};
|
| |
- cloudTitle = h('h3', { class:"font-weight-light" }, "For Cloud Operators");
|
| |
cloudSection = {};
|
| |
cloud = {};
|
| |
|
| |
@@ -450,6 +641,11 @@
|
| |
cloudLaunchable = h('div', { class: "col-12 py-2 my-2" }, [ cloudLaunchableSection ]);
|
| |
|
| |
function createDownloadsSubSection(displayDownloads, contentType, showTitle, imageType) {
|
| |
+ verifyBlurb =
|
| |
+ `<div class="mb-3">
|
| |
+ Verify your download using the detached signature after importing <a href="https://getfedora.org/security/">Fedora's GPG signing keys</a>.
|
| |
+ The detached signature is for the released artifact itself. If there is a good signature from one of the Fedora keys, and the SHA256 checksum matches, then the download is valid.
|
| |
+ </div>`
|
| |
return displayDownloads ? h('div', { class: "pb-2" }, [
|
| |
showTitle ? h('span', {}, contentType + ": ") : null,
|
| |
displayDownloads.location ? h('span', {}, [
|
| |
@@ -466,8 +662,8 @@
|
| |
else {
|
| |
$("#modal-body").empty();
|
| |
let p = document.createElement('p');
|
| |
- let a_checksum = null;
|
| |
- let a_signature = null;
|
| |
+ let aChecksum = null;
|
| |
+ let aSignature = null;
|
| |
// Show SHA256 and initialize the <a> tags if data is available
|
| |
if(displayDownloads.sha256) {
|
| |
let d = document.createElement('div');
|
| |
@@ -475,27 +671,28 @@
|
| |
.html("SHA256: " + displayDownloads.sha256)
|
| |
.appendTo(p);
|
| |
|
| |
- a_checksum = document.createElement('a');
|
| |
- $(a_checksum).attr("href", "data:text/plain;charset=utf-8," + encodeURIComponent("SHA256 (" + getFilename(displayDownloads.location) + ") = " + displayDownloads.sha256))
|
| |
+ aChecksum = document.createElement('a');
|
| |
+ $(aChecksum).attr("href", "data:text/plain;charset=utf-8," + encodeURIComponent("SHA256 (" + getFilename(displayDownloads.location) + ") = " + displayDownloads.sha256))
|
| |
.attr("download", getFilename(displayDownloads.location) + "-CHECKSUM")
|
| |
.html("checksum file");
|
| |
}
|
| |
if(displayDownloads.signature) {
|
| |
- a_signature = document.createElement('a');
|
| |
- $(a_signature).attr("href", displayDownloads.signature)
|
| |
+ aSignature = document.createElement('a');
|
| |
+ $(aSignature).attr("href", displayDownloads.signature)
|
| |
.html("signature");
|
| |
}
|
| |
$(p).appendTo("#modal-body");
|
| |
+ $(verifyBlurb).appendTo("#modal-body");
|
| |
|
| |
// Download the Checksum file and Signature
|
| |
let ol = document.createElement('ol');
|
| |
- if (a_checksum || a_signature) {
|
| |
+ if (aChecksum || aSignature) {
|
| |
let li = document.createElement('li');
|
| |
p = document.createElement('p');
|
| |
$(p).append("Download the ")
|
| |
- .append(a_checksum)
|
| |
- .append(a_checksum && a_signature ? " and " : "")
|
| |
- .append(a_signature);
|
| |
+ .append(aChecksum)
|
| |
+ .append(aChecksum && aSignature ? " and " : "")
|
| |
+ .append(aSignature);
|
| |
$(p).appendTo(li);
|
| |
$(li).appendTo(ol);
|
| |
}
|
| |
@@ -594,31 +791,28 @@
|
| |
}
|
| |
cloud = h('div', { class: "col-12 py-2 my-2" }, [ cloudSection ]);
|
| |
|
| |
- verifyBlurb = h('div', {}, [
|
| |
- h('div', { class:"font-weight-light" }, [
|
| |
- "Verify your download using the detached signature after importing ",
|
| |
- h('a', { attrs: { href: "https://getfedora.org/security/" } }, "Fedora's GPG signing keys"),
|
| |
- ". The detached signature is for the released artifact itself. If there is a good signature from one of the Fedora keys, and the SHA256 checksum matches, then the download is valid."
|
| |
- ])
|
| |
- ]);
|
| |
+ let bareMetalContainer = h('div', { class: "col-lg-6" }, [ bareMetalTitle, bareMetal ]);
|
| |
+ let virtualizedContainer = h('div', { class: "col-lg-6" }, [ virtualizedTitle, virtualized ]);
|
| |
|
| |
- let bare_metal_container = h('div', { class: "col-6" }, [ bareMetalTitle, verifyBlurb, bareMetal ]);
|
| |
- let virtualized_container = h('div', { class: "col-6" }, [ virtualizedTitle, verifyBlurb, virtualized ]);
|
| |
+ let cloudLaunchableContainer = h('div', { class: "col-12 py-2 my-2", attrs: { id: IdPool.cloud_launchable, hidden: this.shownId !== IdPool.cloud_launchable } }, [ cloudLaunchable ]);
|
| |
+ let metalVirtContainer = h('div', { class: "row col-12 py-2 my-2", attrs: { id: IdPool.metal_virtualized, hidden: this.shownId !== IdPool.metal_virtualized } }, [ bareMetalContainer, virtualizedContainer ]);
|
| |
+ let cloudOperatorsContainer = h('div', { class: "col-12 py-2 my-2", attrs: { id: IdPool.cloud_operators, hidden: this.shownId !== IdPool.cloud_operators } }, [ cloud ]);
|
| |
|
| |
- let cloud_launchable_container = h('div', { class: "col-12 py-2 my-2", attrs: { id: IdPool.cloud_launchable, hidden: this.shownId !== IdPool.cloud_launchable } }, [ cloudLaunchableTitle, cloudLaunchable ]);
|
| |
- let metal_virt_container = h('div', { class: "row col-12 py-2 my-2", attrs: { id: IdPool.metal_virtualized, hidden: this.shownId !== IdPool.metal_virtualized } }, [ bare_metal_container, virtualized_container ]);
|
| |
- let cloud_operators_container = h('div', { class: "col-12 py-2 my-2", attrs: { id: IdPool.cloud_operators, hidden: this.shownId !== IdPool.cloud_operators } }, [ cloudTitle, verifyBlurb, cloud ]);
|
| |
+ streamInfoDiv = h('div', { class: "bg-light pt-3" }, [ h('div', { class: "container font-weight-light" }, [ streamSelectContainer ]) ]);
|
| |
+ downloadDiv = h('div', { class: "bg-white pb-5" }, [
|
| |
+ h('div', { class: "container font-weight-light" }, [
|
| |
+ signatureSha256VerificationModal,
|
| |
+ cloudLaunchableContainer,
|
| |
+ metalVirtContainer,
|
| |
+ cloudOperatorsContainer
|
| |
+ ])
|
| |
+ ])
|
| |
|
| |
- return h('div', {}, [
|
| |
- signature_sha256_verification_modal,
|
| |
- stream_select_container,
|
| |
- cloud_launchable_container,
|
| |
- metal_virt_container,
|
| |
- cloud_operators_container
|
| |
- ]);
|
| |
+ return h('div', {}, [h1Title, streamInfoDiv, downloadDiv]);
|
| |
}
|
| |
else {
|
| |
- return h('div', {}, "No stream data found!");
|
| |
+ errorDiv = h('div', { class: "bg-transparent py-5" }, [ h('div', { class: "container font-weight-light" }, "No stream data found!") ]);
|
| |
+ return h('div', {}, [ errorDiv ]);
|
| |
}
|
| |
}
|
| |
})
|
| |
Restyles the Fedora CoreOS Download page based on the initial proposed
design https://pagure.io/fedora-websites/issue/964#comment-576026.
Moreover, dustymabe and abai thought it could be a good idea to add release
stream info and release notes to the top level coreos page:
https://getfedora.org/en/coreos/.
Signed-off-by: Allen Bai abai@redhat.com