This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-website.git
The following commit(s) were added to refs/heads/main by this push:
new 165fab80 Delegate release manifest generation to vendored
WebsiteManifestGenerator.java (#1700)
165fab80 is described below
commit 165fab8029de73af4ef84108961883c41f8306cb
Author: Adriano Machado <[email protected]>
AuthorDate: Sat Jul 25 09:59:08 2026 -0400
Delegate release manifest generation to vendored
WebsiteManifestGenerator.java (#1700)
* Ignoring comments on manifests
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* Delegate release manifest generation to vendored
WebsiteManifestGenerator.java
Replaces the shell-script reimplementation of checksum computation and
immutability/forward-only rules with a byte-identical vendored copy of
apache/camel's own generator, so the two stay in sync mechanically
instead of by hand.
* Add ASF license header to Camel version manifests
Prepends the Apache Software Foundation license header to all release
and latest manifest files. The header is formatted as properties-style
comments (##-prefixed lines) and is safely ignored by manifest parsers
and CLI installers that skip comment lines.
Co-Authored-By: Claude Haiku 4.5 <[email protected]>
* Sync static/install.sh with apache/camel (surface wget/tar errors)
Pick up the installer's surfaced download/extraction errors (wget -nv and
captured tar stderr) so the vendored copy stays byte-identical to the
upstream
source at dsl/camel-jbang/camel-launcher/src/install/install.sh. These land
upstream in apache/camel#25030.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* Allow install.sh and install.ps1 downloads through .htaccess
The sensitive-file-extension block rule denies any .sh file, which
silently 403'd the documented `curl ... install.sh | sh` one-liner.
Carve out install.sh and install.ps1 specifically, scoped to the site
root so same-named files in subdirectories stay blocked.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* Sync installers and manifest generator with apache/camel PR #25072
Adds self-update pin-state tracking to install.sh/install.ps1 and
teaches WebsiteManifestGenerator.java to write install.sha256 (checksums
of install.sh/install.ps1) so `camel self-update` can verify the
installer before running it. Also drops the ASF license header from
generated manifests, matching apache/camel's generator.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* Have update-camel-cli-manifest.sh also sync WebsiteManifestGenerator.java
Step 1 previously only vendored install.sh/install.ps1 from apache/camel
main, leaving scripts/WebsiteManifestGenerator.java to be updated by hand.
Now it also fetches the upstream generator source and reapplies the
"VENDORED COPY" banner, keeping the sync fully mechanical per the file's
own update instructions.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* Sync static/install.ps1 with apache/camel (PowerShell 7 support)
Pick up the installer's PS7 compatibility fixes so the vendored copy stays
byte-identical to the upstream source at
dsl/camel-jbang/camel-launcher/src/install/install.ps1:
- Invoke-WebRequest under PowerShell 7's Core edition runs on HttpClient,
which ignores the ServicePointManager.ServerCertificateValidationCallback
test seam; switch to -SkipCertificateCheck on Core instead.
- The archive entry Unix-mode check no longer throws on entries with mode
bits set, which overflow the checked [uint32] cast from a negative Int32.
These land upstream in apache/camel#25030.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* Note the .htaccess 403 fix in the CLI launcher installer blog post
Readers following the post's one-line install commands between 2026-07-20
and 2026-07-22 could have hit a 403 from the sensitive-file-extension block
rule (fixed in e217ff61). Flag it inline so anyone landing on the post
after hitting that isn't left wondering.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* Use today's date for the installer blog post update note
The note marks when the post itself was amended, not when the underlying
.htaccess fix (e217ff61) landed.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
---------
Co-authored-by: Claude Sonnet 5 <[email protected]>
---
.../2026/07/camel-cli-launcher-installers/index.md | 3 +
scripts/WebsiteManifestGenerator.java | 350 +++++++++++++++++++++
static/.htaccess | 6 +
static/camel-cli/releases/4.13.0.properties | 16 +
static/camel-cli/releases/4.14.0.properties | 16 +
static/camel-cli/releases/4.14.1.properties | 16 +
static/camel-cli/releases/4.14.2.properties | 16 +
static/camel-cli/releases/4.14.3.properties | 16 +
static/camel-cli/releases/4.14.4.properties | 16 +
static/camel-cli/releases/4.14.5.properties | 16 +
static/camel-cli/releases/4.14.6.properties | 16 +
static/camel-cli/releases/4.14.7.properties | 16 +
static/camel-cli/releases/4.14.8.properties | 16 +
static/camel-cli/releases/4.15.0.properties | 16 +
static/camel-cli/releases/4.16.0.properties | 16 +
static/camel-cli/releases/4.17.0.properties | 16 +
static/camel-cli/releases/4.18.0.properties | 16 +
static/camel-cli/releases/4.18.1.properties | 16 +
static/camel-cli/releases/4.18.2.properties | 16 +
static/camel-cli/releases/4.18.3.properties | 16 +
static/camel-cli/releases/4.19.0.properties | 16 +
static/camel-cli/releases/4.20.0.properties | 16 +
static/camel-cli/releases/4.21.0.properties | 16 +
static/camel-cli/releases/latest.properties | 16 +
static/install.ps1 | 75 +++--
static/install.sh | 51 +--
update-camel-cli-manifest.sh | 123 +++-----
27 files changed, 831 insertions(+), 113 deletions(-)
diff --git a/content/blog/2026/07/camel-cli-launcher-installers/index.md
b/content/blog/2026/07/camel-cli-launcher-installers/index.md
index 29a07775..5a777768 100644
--- a/content/blog/2026/07/camel-cli-launcher-installers/index.md
+++ b/content/blog/2026/07/camel-cli-launcher-installers/index.md
@@ -28,6 +28,9 @@ On Windows, in PowerShell:
irm https://camel.apache.org/install.ps1 | iex
```
+**Update (2026-07-25):** A server configuration issue was briefly returning a
+403 for the `install.sh`/`install.ps1` downloads above. This has been fixed.
+
Both installers resolve and install the latest published release by default, or
a specific version if you request one with `--version` (`install.sh`) or
`-Version`
(`install.ps1`). Installation is always per-user and never requires `sudo` or
diff --git a/scripts/WebsiteManifestGenerator.java
b/scripts/WebsiteManifestGenerator.java
new file mode 100644
index 00000000..64ad8f15
--- /dev/null
+++ b/scripts/WebsiteManifestGenerator.java
@@ -0,0 +1,350 @@
+// VENDORED COPY - do not edit here.
+// Source of truth: apache/camel
+//
dsl/camel-jbang/camel-launcher/src/jreleaser/java/WebsiteManifestGenerator.java
+// To update: re-copy that file over this one, then re-apply this banner. The
body below is
+// kept byte-identical to the upstream source so the sync stays a mechanical
copy.
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Intentionally in the default package so camel-package.sh can run this
JDK-only source-file
+// tool directly by path without compiling or loading a package-qualified
launcher class.
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.AtomicMoveNotSupportedException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HexFormat;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * JDK-only tool that computes SHA-256 checksums for a release TAR/ZIP pair
and writes the
+ * website's four-field release manifest ({@code format}, {@code version},
{@code tar_sha256},
+ * {@code zip_sha256}). Per-version manifests are immutable; {@code
latest.properties} can only
+ * move forward to a higher semantic version and cannot silently change
checksums for the same
+ * version. Writes are atomic.
+ *
+ * <p>
+ * Usage: {@code java WebsiteManifestGenerator.java --version X.Y.Z --tar
<path> --zip <path>
+ * --output <dir> --latest <true|false>}
+ */
+public class WebsiteManifestGenerator {
+
+ private static final Pattern VERSION_PATTERN =
Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)$");
+ private static final Set<String> REQUIRED_OPTIONS
+ = new LinkedHashSet<>(List.of("--version", "--tar", "--zip",
"--output", "--latest"));
+ private static final Set<String> OPTIONAL_OPTIONS = Set.of("--install-sh",
"--install-ps1");
+ private static final Set<String> MANIFEST_KEYS
+ = new LinkedHashSet<>(List.of("format", "version", "tar_sha256",
"zip_sha256"));
+ private static final String MANIFEST_FORMAT = "1";
+
+ // Properties-style ASF license header prepended to every generated
manifest. These '#' comment
+ // lines carry no data and are skipped by this tool's own strict re-parser
(parseStrictManifest)
+ // and by the installers (install.sh / install.ps1), which tolerate a
commented manifest.
+ private static final String LICENSE_HEADER
+ = "##
---------------------------------------------------------------------------\n"
+ + "## Licensed to the Apache Software Foundation (ASF) under one
or more\n"
+ + "## contributor license agreements. See the NOTICE file
distributed with\n"
+ + "## this work for additional information regarding copyright
ownership.\n"
+ + "## The ASF licenses this file to You under the Apache
License, Version 2.0\n"
+ + "## (the \"License\"); you may not use this file except in
compliance with\n"
+ + "## the License. You may obtain a copy of the License at\n"
+ + "##\n"
+ + "## http://www.apache.org/licenses/LICENSE-2.0\n"
+ + "##\n"
+ + "## Unless required by applicable law or agreed to in writing,
software\n"
+ + "## distributed under the License is distributed on an \"AS
IS\" BASIS,\n"
+ + "## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied.\n"
+ + "## See the License for the specific language governing
permissions and\n"
+ + "## limitations under the License.\n"
+ + "##
---------------------------------------------------------------------------\n";
+
+ public static void main(String[] args) {
+ try {
+ run(args);
+ } catch (UsageException e) {
+ System.err.println("Error: " + e.getMessage());
+ System.exit(2);
+ } catch (ConflictException | IOException e) {
+ System.err.println("Error: " + e.getMessage());
+ System.exit(1);
+ }
+ }
+
+ private static void run(String[] args) throws IOException {
+ Map<String, String> options = parseArgs(args);
+
+ String version = options.get("--version");
+ if (!VERSION_PATTERN.matcher(version).matches()) {
+ throw new UsageException("'" + version + "' is not a valid release
version (expected X.Y.Z).");
+ }
+
+ Path tar = Paths.get(options.get("--tar"));
+ Path zip = Paths.get(options.get("--zip"));
+ if (!Files.isRegularFile(tar)) {
+ throw new UsageException("TAR artifact not found: " + tar);
+ }
+ if (!Files.isRegularFile(zip)) {
+ throw new UsageException("ZIP artifact not found: " + zip);
+ }
+
+ Path installSh = null;
+ Path installPs1 = null;
+ String installShValue = options.get("--install-sh");
+ if (installShValue != null) {
+ installSh = Paths.get(installShValue);
+ if (!Files.isRegularFile(installSh)) {
+ throw new UsageException("install.sh not found: " + installSh);
+ }
+ }
+ String installPs1Value = options.get("--install-ps1");
+ if (installPs1Value != null) {
+ installPs1 = Paths.get(installPs1Value);
+ if (!Files.isRegularFile(installPs1)) {
+ throw new UsageException("install.ps1 not found: " +
installPs1);
+ }
+ }
+
+ String latestValue = options.get("--latest");
+ boolean latest;
+ if ("true".equals(latestValue)) {
+ latest = true;
+ } else if ("false".equals(latestValue)) {
+ latest = false;
+ } else {
+ throw new UsageException("--latest must be 'true' or 'false' (got
'" + latestValue + "').");
+ }
+
+ Path output = Paths.get(options.get("--output"));
+
+ String tarSha256 = sha256Hex(tar);
+ String zipSha256 = sha256Hex(zip);
+ byte[] manifest = renderManifest(version, tarSha256, zipSha256);
+
+ Path releasesDir = output.resolve("releases");
+ Files.createDirectories(releasesDir);
+ writeVersionManifest(releasesDir.resolve(version + ".properties"),
manifest, version);
+
+ if (latest) {
+ writeLatestManifest(releasesDir.resolve("latest.properties"),
manifest, version);
+ }
+
+ if (installSh != null && installPs1 != null) {
+ writeInstallChecksums(output.getParent(), installSh, installPs1);
+ }
+ }
+
+ private static Map<String, String> parseArgs(String[] args) {
+ Map<String, String> options = new LinkedHashMap<>();
+ int i = 0;
+ while (i < args.length) {
+ String key = args[i];
+ if (!REQUIRED_OPTIONS.contains(key) &&
!OPTIONAL_OPTIONS.contains(key)) {
+ throw new UsageException("unknown option '" + key + "'.");
+ }
+ if (i + 1 >= args.length) {
+ throw new UsageException("option '" + key + "' requires a
value.");
+ }
+ if (options.containsKey(key)) {
+ throw new UsageException("option '" + key + "' was specified
more than once.");
+ }
+ options.put(key, args[i + 1]);
+ i += 2;
+ }
+ for (String required : REQUIRED_OPTIONS) {
+ if (!options.containsKey(required)) {
+ throw new UsageException("missing required option '" +
required + "'.");
+ }
+ }
+ return options;
+ }
+
+ private static byte[] renderManifest(String version, String tarSha256,
String zipSha256) {
+ String content = LICENSE_HEADER
+ + "format=" + MANIFEST_FORMAT + "\n"
+ + "version=" + version + "\n"
+ + "tar_sha256=" + tarSha256 + "\n"
+ + "zip_sha256=" + zipSha256 + "\n";
+ return content.getBytes(StandardCharsets.UTF_8);
+ }
+
+ private static void writeVersionManifest(Path versionFile, byte[]
manifest, String version) throws IOException {
+ if (Files.exists(versionFile)) {
+ byte[] existing = Files.readAllBytes(versionFile);
+ if (Arrays.equals(existing, manifest)) {
+ return;
+ }
+ throw new ConflictException("version manifest for " + version + "
already exists with different content"
+ + " (" + versionFile + ") - version
manifests are immutable.");
+ }
+ atomicWrite(versionFile, manifest);
+ }
+
+ private static void writeLatestManifest(Path latestFile, byte[] manifest,
String version) throws IOException {
+ if (!Files.exists(latestFile)) {
+ atomicWrite(latestFile, manifest);
+ return;
+ }
+
+ byte[] existing = Files.readAllBytes(latestFile);
+ if (Arrays.equals(existing, manifest)) {
+ return;
+ }
+
+ Map<String, String> existingFields = parseStrictManifest(existing,
latestFile);
+ String existingVersion = existingFields.get("version");
+ int cmp = compareSemver(version, existingVersion);
+ if (cmp < 0) {
+ throw new ConflictException(
+ "latest.properties already points at a newer version (" +
existingVersion + "); refusing to"
+ + " move backward to " + version +
".");
+ } else if (cmp == 0) {
+ throw new ConflictException("latest.properties already has
different checksums for version " + version
+ + " - refusing to overwrite.");
+ }
+ atomicWrite(latestFile, manifest);
+ }
+
+ // install.sh/install.ps1 aren't versioned the way the release archive is
- they always describe
+ // "how to install whatever is currently latest," so unlike
writeVersionManifest/writeLatestManifest
+ // there's no immutability or monotonic-version invariant to enforce here:
this file is simply
+ // overwritten every release with the checksums of whatever
install.sh/install.ps1 currently are.
+ private static void writeInstallChecksums(Path websiteRoot, Path
installSh, Path installPs1) throws IOException {
+ String content = "install_sh_sha256=" + sha256Hex(installSh) + "\n"
+ + "install_ps1_sha256=" + sha256Hex(installPs1) +
"\n";
+ atomicWrite(websiteRoot.resolve("install.sha256"),
content.getBytes(StandardCharsets.UTF_8));
+ }
+
+ private static Map<String, String> parseStrictManifest(byte[] bytes, Path
source) {
+ String content = new String(bytes, StandardCharsets.UTF_8);
+ Map<String, String> fields = new LinkedHashMap<>();
+ for (String line : content.split("\n", -1)) {
+ // Skip blank lines and '#' comment lines (e.g. the ASF license
header this tool now
+ // prepends), so re-reading a previously generated
latest.properties stays valid.
+ if (line.isEmpty() || line.startsWith("#")) {
+ continue;
+ }
+ int eq = line.indexOf('=');
+ if (eq < 0) {
+ throw new ConflictException("malformed manifest line in " +
source + ": '" + line + "'.");
+ }
+ String key = line.substring(0, eq);
+ if (fields.containsKey(key)) {
+ throw new ConflictException("malformed manifest in " + source
+ ": duplicate key '" + key + "'.");
+ }
+ fields.put(key, line.substring(eq + 1));
+ }
+ if (!fields.keySet().equals(MANIFEST_KEYS)) {
+ throw new ConflictException("malformed manifest in " + source + ":
expected keys " + MANIFEST_KEYS
+ + " but found " + fields.keySet() +
".");
+ }
+ if (!MANIFEST_FORMAT.equals(fields.get("format"))) {
+ throw new ConflictException("malformed manifest in " + source + ":
unsupported format '"
+ + fields.get("format") + "'.");
+ }
+ if (!VERSION_PATTERN.matcher(fields.get("version")).matches()) {
+ throw new ConflictException("malformed manifest in " + source + ":
invalid version '"
+ + fields.get("version") + "'.");
+ }
+ assertSha256(fields.get("tar_sha256"), source, "tar_sha256");
+ assertSha256(fields.get("zip_sha256"), source, "zip_sha256");
+ return fields;
+ }
+
+ private static void assertSha256(String value, Path source, String key) {
+ if (!value.matches("[0-9a-f]{64}")) {
+ throw new ConflictException("malformed manifest in " + source + ":
invalid " + key + " '" + value + "'.");
+ }
+ }
+
+ private static int compareSemver(String a, String b) {
+ int[] pa = semverParts(a);
+ int[] pb = semverParts(b);
+ for (int i = 0; i < 3; i++) {
+ int c = Integer.compare(pa[i], pb[i]);
+ if (c != 0) {
+ return c;
+ }
+ }
+ return 0;
+ }
+
+ private static int[] semverParts(String version) {
+ Matcher m = VERSION_PATTERN.matcher(version);
+ if (!m.matches()) {
+ throw new ConflictException("invalid semantic version '" + version
+ "'.");
+ }
+ return new int[] { Integer.parseInt(m.group(1)),
Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)) };
+ }
+
+ private static void atomicWrite(Path target, byte[] bytes) throws
IOException {
+ Path dir = target.toAbsolutePath().getParent();
+ Path tmp = Files.createTempFile(dir, "wmg-", ".tmp");
+ try {
+ Files.write(tmp, bytes);
+ try {
+ Files.move(tmp, target, StandardCopyOption.ATOMIC_MOVE,
StandardCopyOption.REPLACE_EXISTING);
+ } catch (AtomicMoveNotSupportedException e) {
+ Files.move(tmp, target, StandardCopyOption.REPLACE_EXISTING);
+ }
+ } finally {
+ Files.deleteIfExists(tmp);
+ }
+ }
+
+ private static String sha256Hex(Path file) throws IOException {
+ MessageDigest digest;
+ try {
+ digest = MessageDigest.getInstance("SHA-256");
+ } catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("SHA-256 is required by the JDK
and must always be available.", e);
+ }
+ try (InputStream in = Files.newInputStream(file)) {
+ byte[] buffer = new byte[8192];
+ int read;
+ while ((read = in.read(buffer)) != -1) {
+ digest.update(buffer, 0, read);
+ }
+ }
+ return HexFormat.of().formatHex(digest.digest());
+ }
+
+ private static final class UsageException extends RuntimeException {
+ UsageException(String message) {
+ super(message);
+ }
+ }
+
+ private static final class ConflictException extends RuntimeException {
+ ConflictException(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/static/.htaccess b/static/.htaccess
index 1ff95fd1..0acee1df 100644
--- a/static/.htaccess
+++ b/static/.htaccess
@@ -1449,6 +1449,12 @@ AddDefaultCharset utf-8
<FilesMatch
"(^#.*#|\.(bak|conf|dist|fla|in[ci]|log|orig|psd|sh|sql|sw[op])|~)$">
Require all denied
</FilesMatch>
+ # install.sh and install.ps1 are intentionally public installer scripts,
not
+ # leaked build/config files. Scoped to the site root only, so a same-named
+ # file in a subdirectory stays blocked by the FilesMatch rule above.
+ <If "%{REQUEST_URI} =~ m#^/(install\.sh|install\.ps1)$#">
+ Require all granted
+ </If>
</IfModule>
# ----------------------------------------------------------------------
diff --git a/static/camel-cli/releases/4.13.0.properties
b/static/camel-cli/releases/4.13.0.properties
index 0f9a940b..99626823 100644
--- a/static/camel-cli/releases/4.13.0.properties
+++ b/static/camel-cli/releases/4.13.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.13.0
tar_sha256=3d1a31b2ecb6d345fa491574e400c6099d68b5a7349b402c7ee4c01cc840645b
diff --git a/static/camel-cli/releases/4.14.0.properties
b/static/camel-cli/releases/4.14.0.properties
index 077e9654..3ce5f2f7 100644
--- a/static/camel-cli/releases/4.14.0.properties
+++ b/static/camel-cli/releases/4.14.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.0
tar_sha256=23efaa431f0faa1ee3183e333b83601952277ab9f881d448c52564abe7447ec0
diff --git a/static/camel-cli/releases/4.14.1.properties
b/static/camel-cli/releases/4.14.1.properties
index 28c78b56..bc721266 100644
--- a/static/camel-cli/releases/4.14.1.properties
+++ b/static/camel-cli/releases/4.14.1.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.1
tar_sha256=4a1157f2a6a40c992335a246c759c01706be209852a652cfd5633e37d61b8442
diff --git a/static/camel-cli/releases/4.14.2.properties
b/static/camel-cli/releases/4.14.2.properties
index 0854fbea..d770d5f8 100644
--- a/static/camel-cli/releases/4.14.2.properties
+++ b/static/camel-cli/releases/4.14.2.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.2
tar_sha256=4c59276f1ffc965ef33c1f591abb5a6837db89611902d18ba2cd81747b620bce
diff --git a/static/camel-cli/releases/4.14.3.properties
b/static/camel-cli/releases/4.14.3.properties
index 4e02380e..38254194 100644
--- a/static/camel-cli/releases/4.14.3.properties
+++ b/static/camel-cli/releases/4.14.3.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.3
tar_sha256=bf07215a8a5612f13435cc002aee3b2833ba6d221eebe9202e5a649d95e5a5b7
diff --git a/static/camel-cli/releases/4.14.4.properties
b/static/camel-cli/releases/4.14.4.properties
index 9cab236f..6f06d516 100644
--- a/static/camel-cli/releases/4.14.4.properties
+++ b/static/camel-cli/releases/4.14.4.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.4
tar_sha256=cf23867122e719d2e41dbf1975807f7a4b5e126c1e4e0adfd1f8b234a18b2cee
diff --git a/static/camel-cli/releases/4.14.5.properties
b/static/camel-cli/releases/4.14.5.properties
index 2776611b..93a1c0b9 100644
--- a/static/camel-cli/releases/4.14.5.properties
+++ b/static/camel-cli/releases/4.14.5.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.5
tar_sha256=77d4eda924c97687b6c8d09d34e5c15187ed214c5284edc8086c612d73c32896
diff --git a/static/camel-cli/releases/4.14.6.properties
b/static/camel-cli/releases/4.14.6.properties
index d95ad3d9..3b6814da 100644
--- a/static/camel-cli/releases/4.14.6.properties
+++ b/static/camel-cli/releases/4.14.6.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.6
tar_sha256=16826411fc4553a92d1df1c633be942f5ec315911ec48e062ca2f65cd228a68a
diff --git a/static/camel-cli/releases/4.14.7.properties
b/static/camel-cli/releases/4.14.7.properties
index 61fe8184..6c38a9e2 100644
--- a/static/camel-cli/releases/4.14.7.properties
+++ b/static/camel-cli/releases/4.14.7.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.7
tar_sha256=d74214be90d330721292a50d1922c553f438348ab5e05832f84c6d4857dd1f94
diff --git a/static/camel-cli/releases/4.14.8.properties
b/static/camel-cli/releases/4.14.8.properties
index ac58787d..aa4b1abe 100644
--- a/static/camel-cli/releases/4.14.8.properties
+++ b/static/camel-cli/releases/4.14.8.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.14.8
tar_sha256=21b6e2ea881cf06c99dbf6502cbd3dc98f59e44f8491b8d22c4758b3942fa37f
diff --git a/static/camel-cli/releases/4.15.0.properties
b/static/camel-cli/releases/4.15.0.properties
index cf55369c..09424fd9 100644
--- a/static/camel-cli/releases/4.15.0.properties
+++ b/static/camel-cli/releases/4.15.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.15.0
tar_sha256=bc7d40e4ce18b8a195e1e6333e8ec147efe697a2500dd15840c6b9ca6abbf14a
diff --git a/static/camel-cli/releases/4.16.0.properties
b/static/camel-cli/releases/4.16.0.properties
index 576c1d6b..fcaffbd8 100644
--- a/static/camel-cli/releases/4.16.0.properties
+++ b/static/camel-cli/releases/4.16.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.16.0
tar_sha256=19e784eee53213b18cb620e3b3888dcc1fc4d925c41b48846db7825d38b28653
diff --git a/static/camel-cli/releases/4.17.0.properties
b/static/camel-cli/releases/4.17.0.properties
index 0955bdcf..080572f1 100644
--- a/static/camel-cli/releases/4.17.0.properties
+++ b/static/camel-cli/releases/4.17.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.17.0
tar_sha256=6aae94b30a33a04c2daed938333956f6d41615fc0edd9a27219dbe9665595f72
diff --git a/static/camel-cli/releases/4.18.0.properties
b/static/camel-cli/releases/4.18.0.properties
index 2692894b..5f69a26a 100644
--- a/static/camel-cli/releases/4.18.0.properties
+++ b/static/camel-cli/releases/4.18.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.18.0
tar_sha256=3194acbe30530a8814a58ad86042a43800435e459ab8e6fc17141d4a6d05d85f
diff --git a/static/camel-cli/releases/4.18.1.properties
b/static/camel-cli/releases/4.18.1.properties
index 857c7901..aad0a92a 100644
--- a/static/camel-cli/releases/4.18.1.properties
+++ b/static/camel-cli/releases/4.18.1.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.18.1
tar_sha256=efe028eda43216d1150828aed2449c0af8c62f35446fd0c4b3835de2a02a8093
diff --git a/static/camel-cli/releases/4.18.2.properties
b/static/camel-cli/releases/4.18.2.properties
index d6674c04..fd34e0cc 100644
--- a/static/camel-cli/releases/4.18.2.properties
+++ b/static/camel-cli/releases/4.18.2.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.18.2
tar_sha256=5288962fee8cf22df2e3717350205fd1cdc47ba449436a43a677ba0cb84a49aa
diff --git a/static/camel-cli/releases/4.18.3.properties
b/static/camel-cli/releases/4.18.3.properties
index 47d97000..4dfffb21 100644
--- a/static/camel-cli/releases/4.18.3.properties
+++ b/static/camel-cli/releases/4.18.3.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.18.3
tar_sha256=8128d5c8259f72b29b25f857f97eb7f892067801fc2c2e2aa53ca1c9a780d01d
diff --git a/static/camel-cli/releases/4.19.0.properties
b/static/camel-cli/releases/4.19.0.properties
index 0e7edbcc..28b8370d 100644
--- a/static/camel-cli/releases/4.19.0.properties
+++ b/static/camel-cli/releases/4.19.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.19.0
tar_sha256=21b198c34b0028f3e0241e14f81af6e840a10e6ba0f2fb28f16055270a2c35d3
diff --git a/static/camel-cli/releases/4.20.0.properties
b/static/camel-cli/releases/4.20.0.properties
index 3e4bdeda..f66452aa 100644
--- a/static/camel-cli/releases/4.20.0.properties
+++ b/static/camel-cli/releases/4.20.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.20.0
tar_sha256=5f2332580392f9c77b2489c728e3052848fe5b8c201ae701fe2bf37b83351782
diff --git a/static/camel-cli/releases/4.21.0.properties
b/static/camel-cli/releases/4.21.0.properties
index 8ca2416e..305bcf3d 100644
--- a/static/camel-cli/releases/4.21.0.properties
+++ b/static/camel-cli/releases/4.21.0.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.21.0
tar_sha256=24c247b9418292bce794b8ad2333691263c3d0de9a4a0fbc767942669b71984c
diff --git a/static/camel-cli/releases/latest.properties
b/static/camel-cli/releases/latest.properties
index 8ca2416e..305bcf3d 100644
--- a/static/camel-cli/releases/latest.properties
+++ b/static/camel-cli/releases/latest.properties
@@ -1,3 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
format=1
version=4.21.0
tar_sha256=24c247b9418292bce794b8ad2333691263c3d0de9a4a0fbc767942669b71984c
diff --git a/static/install.ps1 b/static/install.ps1
index c57fc6b3..a7ef356f 100644
--- a/static/install.ps1
+++ b/static/install.ps1
@@ -29,6 +29,7 @@ $CaCertPath = $env:CAMEL_INSTALL_CA_CERT
$InstallRoot = Join-Path $env:LOCALAPPDATA 'Apache Camel'
$DataRoot = Join-Path $InstallRoot 'cli\versions'
$BinDir = Join-Path $InstallRoot 'bin'
+$PinnedVersionFile = Join-Path $InstallRoot 'cli\pinned-version'
function Fail {
param([string] $Message)
@@ -48,31 +49,44 @@ function Test-ValidSha256 {
}
}
+$UseSkipCertificateCheck = $false
if ($CaCertPath) {
# Test seam only: trusts the loopback fixture's self-signed CA for this
process without touching
# the real Windows certificate store. Production installs never set
CAMEL_INSTALL_CA_CERT.
- $installerCaCert = New-Object
System.Security.Cryptography.X509Certificates.X509Certificate2($CaCertPath)
- [System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.SecurityProtocolType]::Tls12
- [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {
- param($sender, $certificate, $chain, $sslPolicyErrors)
- $verifyChain = New-Object
System.Security.Cryptography.X509Certificates.X509Chain
- $verifyChain.ChainPolicy.ExtraStore.Add($installerCaCert) | Out-Null
- $verifyChain.ChainPolicy.RevocationMode =
[System.Security.Cryptography.X509Certificates.X509RevocationMode]::NoCheck
- $verifyChain.ChainPolicy.VerificationFlags =
[System.Security.Cryptography.X509Certificates.X509VerificationFlags]::AllowUnknownCertificateAuthority
- $leaf = New-Object
System.Security.Cryptography.X509Certificates.X509Certificate2($certificate)
- if (-not $verifyChain.Build($leaf)) {
- return $false
- }
- $root = $verifyChain.ChainElements[$verifyChain.ChainElements.Count -
1].Certificate
- return $root.Thumbprint -eq $installerCaCert.Thumbprint
- }.GetNewClosure()
+ if ($PSVersionTable.PSEdition -eq 'Core') {
+ # PowerShell 7+'s Invoke-WebRequest runs on HttpClient, which never
consults
+ # ServicePointManager.ServerCertificateValidationCallback (a Windows
PowerShell/.NET Framework-
+ # only hook) - it's silently ignored, so the callback below never
rejects a bad cert either.
+ # Pin trust via -SkipCertificateCheck on the call instead.
+ $UseSkipCertificateCheck = $true
+ } else {
+ $installerCaCert = New-Object
System.Security.Cryptography.X509Certificates.X509Certificate2($CaCertPath)
+ [System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.SecurityProtocolType]::Tls12
+ [System.Net.ServicePointManager]::ServerCertificateValidationCallback
= {
+ param($sender, $certificate, $chain, $sslPolicyErrors)
+ $verifyChain = New-Object
System.Security.Cryptography.X509Certificates.X509Chain
+ $verifyChain.ChainPolicy.ExtraStore.Add($installerCaCert) |
Out-Null
+ $verifyChain.ChainPolicy.RevocationMode =
[System.Security.Cryptography.X509Certificates.X509RevocationMode]::NoCheck
+ $verifyChain.ChainPolicy.VerificationFlags =
[System.Security.Cryptography.X509Certificates.X509VerificationFlags]::AllowUnknownCertificateAuthority
+ $leaf = New-Object
System.Security.Cryptography.X509Certificates.X509Certificate2($certificate)
+ if (-not $verifyChain.Build($leaf)) {
+ return $false
+ }
+ $root =
$verifyChain.ChainElements[$verifyChain.ChainElements.Count - 1].Certificate
+ return $root.Thumbprint -eq $installerCaCert.Thumbprint
+ }.GetNewClosure()
+ }
}
# Downloads $Url to $OutFile; used for both the manifest and archive fetches.
function Save-RemoteFile {
param([string] $Url, [string] $OutFile)
try {
- Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing |
Out-Null
+ if ($UseSkipCertificateCheck) {
+ Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing
-SkipCertificateCheck | Out-Null
+ } else {
+ Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing |
Out-Null
+ }
} catch {
Fail "failed to download $Url"
}
@@ -82,7 +96,10 @@ function Save-RemoteFile {
function Read-Manifest {
param([string] $Path)
- $lines = @(Get-Content -LiteralPath $Path -Encoding UTF8)
+ # Drop comment lines (properties-style '#', and the '##' ASF license
header the website's manifest
+ # generator prepends) before validation; they carry no data. Blank lines
are kept so they still
+ # trip the exactly-four-lines / blank-line checks below.
+ $lines = @(Get-Content -LiteralPath $Path -Encoding UTF8 | Where-Object {
-not $_.StartsWith('#') })
if ($lines.Count -ne 4) {
Fail "manifest must contain exactly four lines"
}
@@ -153,7 +170,11 @@ function Test-ArchiveEntry {
if ($segments -contains '..') {
Fail "archive contains a path traversal entry: $name"
}
- $unixMode = ([uint32]$entry.ExternalAttributes -shr 16) -band
0xF000
+ # ExternalAttributes is a signed Int32 whose upper 16 bits carry
the Unix mode; any entry
+ # with mode bits set (e.g. 0100644, universal for a POSIX-built
archive) overflows into
+ # negative range there. [uint32] is a checked cast that throws on
a negative input, so mask
+ # to the low 32 bits as Int64 first to reinterpret the same bit
pattern unsigned.
+ $unixMode = ([uint32]($entry.ExternalAttributes -band 0xFFFFFFFFL)
-shr 16) -band 0xF000
if ($unixMode -eq 0xA000) {
Fail "archive contains a symbolic link or reparse point entry,
which is not allowed"
}
@@ -211,6 +232,23 @@ function Set-CamelShim {
Move-Item -LiteralPath $tempShim -Destination $finalShim -Force
}
+# Records whether this install is pinned to an explicit version, so `camel
self-update` can refuse to move
+# a deliberately pinned install. Skipped when CAMEL_INSTALL_SELF_UPDATE=true:
self-update always passes its
+# own resolved -Version for TOCTOU-safety (see SelfUpdateCommand), which is
not a human pinning a version
+# and must not create or clear a pin either way.
+function Update-PinState {
+ param([string] $RequestedVersion, [string] $ResolvedVersion)
+
+ if ($env:CAMEL_INSTALL_SELF_UPDATE -eq 'true') {
+ return
+ }
+ if ($RequestedVersion) {
+ Set-Content -LiteralPath $PinnedVersionFile -Value $ResolvedVersion
-NoNewline
+ } elseif (Test-Path -LiteralPath $PinnedVersionFile) {
+ Remove-Item -LiteralPath $PinnedVersionFile -Force
+ }
+}
+
# Adds $Dir once, case-insensitively, to the current user's PATH
(registry-level, no elevation) and to
# this process; the machine PATH is never written. The value is read and
written through the registry
# with DoNotExpandEnvironmentNames so existing %VAR% references are preserved
rather than flattened,
@@ -282,6 +320,7 @@ try {
Test-StagedLauncher -LauncherPath $stagedLauncher
Set-CamelShim -Version $resolvedVersion -StagedRoot $stagedRoot
+ Update-PinState -RequestedVersion $Version -ResolvedVersion
$resolvedVersion
Add-UserPath -Dir $BinDir
Write-Host "Installed Camel CLI $resolvedVersion to $(Join-Path $DataRoot
$resolvedVersion)"
diff --git a/static/install.sh b/static/install.sh
old mode 100644
new mode 100755
index 7879686f..6057dd69
--- a/static/install.sh
+++ b/static/install.sh
@@ -38,21 +38,12 @@ is_valid_version() {
'' | .* | *. | *..* | *[!0-9.]*) return 1 ;;
esac
# The case above guarantees digits and single dots only, with no leading,
trailing, or doubled
- # dot, so a valid X.Y.Z is exactly the value containing two dots (three
non-empty components).
- rest="$v"
- dots=0
- while :; do
- case "$rest" in
- *.*)
- dots=$((dots + 1))
- rest="${rest#*.}"
- ;;
- *)
- break
- ;;
- esac
- done
- [ "$dots" -eq 2 ]
+ # dot, so a valid X.Y.Z is exactly the value with three non-empty
components (two dots).
+ case "$v" in
+ *.*.*.*) return 1 ;;
+ *.*.*) return 0 ;;
+ *) return 1 ;;
+ esac
}
validate_sha256() {
@@ -75,9 +66,9 @@ fetch() {
fi
elif command -v wget >/dev/null 2>&1; then
if [ -n "$ca_cert" ]; then
- wget -q --ca-certificate="$ca_cert" -O "$outfile" "$url"
+ wget -nv --ca-certificate="$ca_cert" -O "$outfile" "$url"
else
- wget -q -O "$outfile" "$url"
+ wget -nv -O "$outfile" "$url"
fi
else
fail "curl or wget is required to install the Camel CLI"
@@ -114,6 +105,12 @@ parse_manifest() {
# Tolerate a manifest served with CRLF line endings, matching the
PowerShell parser.
key="${key%"$cr"}"
value="${value%"$cr"}"
+ # Skip comment lines (properties-style '#', and the '##' ASF license
header the website's
+ # manifest generator prepends). They carry no data, so they are
neither counted toward the
+ # required line total nor validated as key=value pairs. Blank lines
are still rejected below.
+ case "$key" in
+ \#*) continue ;;
+ esac
line_count=$((line_count + 1))
[ -n "$key" ] || fail "manifest contains a blank line"
[ -n "$value" ] || fail "manifest key '$key' has an empty value"
@@ -163,11 +160,12 @@ validate_tar() {
expected_root="camel-launcher-$version"
listing="$staging_dir/listing.txt"
- tar -tzf "$archive" > "$listing" 2>/dev/null || fail "archive is not a
valid tar.gz"
+ tar_err=$(tar -tzf "$archive" 2>&1 1>"$listing") || fail "archive is not a
valid tar.gz${tar_err:+: $tar_err}"
verbose_listing="$staging_dir/listing-verbose.txt"
# LC_ALL=C keeps tar's hard-link annotation as the literal 'link to'
string; GNU tar localizes it.
- LC_ALL=C tar -tvzf "$archive" > "$verbose_listing" 2>/dev/null || fail
"archive is not a valid tar.gz"
+ tar_err=$(LC_ALL=C tar -tvzf "$archive" 2>&1 1>"$verbose_listing") \
+ || fail "archive is not a valid tar.gz${tar_err:+: $tar_err}"
# tar -tv renders symlinks as 'name -> target' and hard links as 'name
link to target'. Matching
# those substrings could in theory over-reject a regular file whose name
contains ' -> ' or
# ' link to '; that fail-closed bias is deliberate, the release archive
never carries such names.
@@ -220,6 +218,20 @@ activate() {
mv -f "$tmp_link" "$bin_dir/camel"
}
+# Records whether this install is pinned to an explicit version, so `camel
self-update` can refuse to move
+# a deliberately pinned install. Skipped when CAMEL_INSTALL_SELF_UPDATE=true:
self-update always passes its
+# own resolved --version for TOCTOU-safety (see SelfUpdateCommand), which is
not a human pinning a version
+# and must not create or clear a pin either way.
+update_pin_state() {
+ [ "${CAMEL_INSTALL_SELF_UPDATE:-}" = "true" ] && return 0
+ pinned_version_file="$camel_cli_root/pinned-version"
+ if [ -n "$requested_version" ]; then
+ printf '%s\n' "$version" > "$pinned_version_file"
+ else
+ rm -f "$pinned_version_file"
+ fi
+}
+
requested_version=""
while [ $# -gt 0 ]; do
case "$1" in
@@ -281,6 +293,7 @@ staged_root_dir="$extract_dir/camel-launcher-$version"
verify_staged "$staged_root_dir/bin/camel.sh"
activate "$version" "$staged_root_dir"
+update_pin_state
case ":$PATH:" in
*":$bin_dir:"*) ;;
diff --git a/update-camel-cli-manifest.sh b/update-camel-cli-manifest.sh
index 5afe5ad8..5b78a0a8 100755
--- a/update-camel-cli-manifest.sh
+++ b/update-camel-cli-manifest.sh
@@ -5,21 +5,28 @@
# Usage: ./update-camel-cli-manifest.sh <version> [--latest]
#
# 1. Fetches install.sh and install.ps1 from apache/camel main and writes them
-# byte-identical to static/install.sh and static/install.ps1.
-# 2. Downloads camel-launcher-<version>-bin.{tar.gz,zip} from Maven Central,
-# computes SHA-256, and writes
static/camel-cli/releases/<version>.properties.
+# byte-identical to static/install.sh and static/install.ps1. Also
refreshes the
+# vendored scripts/WebsiteManifestGenerator.java from the same apache/camel
source,
+# reapplying the "VENDORED COPY" banner on top of the byte-identical
upstream body.
+# 2. Downloads camel-launcher-<version>-bin.{tar.gz,zip} from Maven Central and
+# delegates to scripts/WebsiteManifestGenerator.java (a vendored copy of the
+# apache/camel tool) to compute SHA-256 and write the release manifests.
# 3. With --latest, updates latest.properties, but only if <version> is newer.
#
-# The manifest format (format=1, version, tar_sha256, zip_sha256) mirrors
-# WebsiteManifestGenerator.java in apache/camel and is parsed by the
installers.
+# The manifest format (format=1, version, tar_sha256, zip_sha256) and all
+# immutability / forward-only rules live in the single Java implementation;
+# this script no longer reimplements them. The generator also writes
+# static/install.sha256 (checksums of install.sh/install.ps1), which
+# `camel self-update` uses to verify the installer before running it.
set -eu
MAIN_RAW="https://raw.githubusercontent.com/apache/camel/main/dsl/camel-jbang/camel-launcher/src/install"
+GENERATOR_RAW_URL="https://raw.githubusercontent.com/apache/camel/main/dsl/camel-jbang/camel-launcher/src/jreleaser/java/WebsiteManifestGenerator.java"
MAVEN_BASE="https://repo1.maven.org/maven2/org/apache/camel/camel-launcher"
-repo_root=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+repo_root=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
static_dir="$repo_root/static"
-releases_dir="$static_dir/camel-cli/releases"
+generator="$repo_root/scripts/WebsiteManifestGenerator.java"
die() { echo "error: $*" >&2; exit 1; }
usage() { echo "Usage: $0 <version> [--latest]" >&2; exit 2; }
@@ -38,33 +45,13 @@ done
echo "$version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || die "version must be
X.Y.Z: $version"
-sha256() {
- if command -v sha256sum >/dev/null 2>&1; then
- sha256sum "$1" | awk '{print $1}'
- elif command -v shasum >/dev/null 2>&1; then
- shasum -a 256 "$1" | awk '{print $1}'
- else
- die "need sha256sum or shasum"
- fi
-}
-
-# 0 (true) if $1 is strictly newer than $2 (both X.Y.Z numeric).
-version_gt() {
- i=1
- while [ "$i" -le 3 ]; do
- fa=$(echo "$1" | cut -d. -f"$i")
- fb=$(echo "$2" | cut -d. -f"$i")
- [ "$fa" -gt "$fb" ] && return 0
- [ "$fa" -lt "$fb" ] && return 1
- i=$((i + 1))
- done
- return 1
-}
+command -v java >/dev/null 2>&1 || die "java (JDK 17+) is required to run
$generator"
+[ -f "$generator" ] || die "generator not found: $generator"
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT INT TERM
-# --- 1. Vendor the installer scripts from apache/camel main ------------------
+# --- 1. Vendor the installer scripts and manifest generator from apache/camel
main ------
mkdir -p "$static_dir"
for script in install.sh install.ps1; do
echo "Fetching $script from apache/camel main"
@@ -74,58 +61,42 @@ for script in install.sh install.ps1; do
echo " wrote static/$script"
done
-# --- 2. Compute checksums from the Maven Central -bin archives ---------------
+echo "Fetching WebsiteManifestGenerator.java from apache/camel main"
+curl -fsSL "$GENERATOR_RAW_URL" -o "$tmp/WebsiteManifestGenerator.java" \
+ || die "could not download WebsiteManifestGenerator.java from
$GENERATOR_RAW_URL"
+{
+ printf '// VENDORED COPY - do not edit here.\n'
+ printf '// Source of truth: apache/camel\n'
+ printf '//
dsl/camel-jbang/camel-launcher/src/jreleaser/java/WebsiteManifestGenerator.java\n'
+ printf '// To update: re-copy that file over this one, then re-apply this
banner. The body below is\n'
+ printf '// kept byte-identical to the upstream source so the sync stays a
mechanical copy.\n'
+ printf '\n'
+ cat "$tmp/WebsiteManifestGenerator.java"
+} > "$tmp/WebsiteManifestGenerator.java.bannered"
+mv "$tmp/WebsiteManifestGenerator.java.bannered" "$generator"
+echo " wrote scripts/WebsiteManifestGenerator.java"
+
+# --- 2. Download the Maven Central -bin archives ----------------------------
tar_url="$MAVEN_BASE/$version/camel-launcher-$version-bin.tar.gz"
zip_url="$MAVEN_BASE/$version/camel-launcher-$version-bin.zip"
echo "Downloading $tar_url"
curl -fsSL "$tar_url" -o "$tmp/archive.tar.gz" || die "could not download
$tar_url"
echo "Downloading $zip_url"
curl -fsSL "$zip_url" -o "$tmp/archive.zip" || die "could not download
$zip_url"
-tar_sha256=$(sha256 "$tmp/archive.tar.gz")
-zip_sha256=$(sha256 "$tmp/archive.zip")
-
-manifest_body() {
- printf 'format=1\nversion=%s\ntar_sha256=%s\nzip_sha256=%s\n' \
- "$version" "$tar_sha256" "$zip_sha256"
-}
-
-write_manifest() {
- dest=$1
- tmpf=$(mktemp "$tmp/manifest.XXXXXX")
- manifest_body >"$tmpf"
- mv "$tmpf" "$dest"
- echo " wrote ${dest#"$repo_root"/}"
-}
-
-mkdir -p "$releases_dir"
-version_file="$releases_dir/$version.properties"
-
-# --- 3. Per-version manifest (immutable) ------------------------------------
-if [ -f "$version_file" ]; then
- if manifest_body | cmp -s - "$version_file"; then
- echo "$version.properties already up to date"
- else
- die "$version.properties exists with different checksums; per-version
manifests are immutable"
- fi
-else
- write_manifest "$version_file"
-fi
-# --- 4. latest.properties (forward-only) ------------------------------------
-if [ "$update_latest" -eq 1 ]; then
- latest_file="$releases_dir/latest.properties"
- if [ -f "$latest_file" ]; then
- current=$(sed -n 's/^version=//p' "$latest_file")
- if [ "$current" = "$version" ]; then
- echo "latest.properties already at $version"
- elif version_gt "$version" "$current"; then
- write_manifest "$latest_file"
- else
- die "latest.properties already at $current (newer than $version);
refusing to move backward"
- fi
- else
- write_manifest "$latest_file"
- fi
-fi
+# --- 3. Write the manifests via the vendored Java generator ------------------
+# The generator computes checksums, writes
static/camel-cli/releases/<version>.properties
+# (immutable) and, when --latest is given, advances latest.properties
forward-only.
+if [ "$update_latest" -eq 1 ]; then latest=true; else latest=false; fi
+echo "Generating manifests via scripts/WebsiteManifestGenerator.java"
+java "$generator" \
+ --version "$version" \
+ --tar "$tmp/archive.tar.gz" \
+ --zip "$tmp/archive.zip" \
+ --output "$static_dir/camel-cli" \
+ --latest "$latest" \
+ --install-sh "$static_dir/install.sh" \
+ --install-ps1 "$static_dir/install.ps1" \
+ || die "WebsiteManifestGenerator failed"
echo "Done."