Merge branch 'rust-port': screenshots and macOS cross-build support
@@ -25,7 +25,13 @@ serde_json = "1"
|
|||||||
jiff = "0.2"
|
jiff = "0.2"
|
||||||
tar = { version = "0.4.46", default-features = false }
|
tar = { version = "0.4.46", default-features = false }
|
||||||
flate2 = { version = "1.1", default-features = false, features = ["rust_backend"] }
|
flate2 = { version = "1.1", default-features = false, features = ["rust_backend"] }
|
||||||
ureq = { version = "3.4", default-features = false, features = ["rustls", "platform-verifier", "gzip"] }
|
ureq = { version = "3.4", default-features = false, features = ["rustls", "gzip"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["system-roots"]
|
||||||
|
# Verify TLS certificates against the operating system's trust store. Off,
|
||||||
|
# the bundled Mozilla roots are used (for cross-built macOS binaries).
|
||||||
|
system-roots = ["ureq/platform-verifier"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
aes = "0.9"
|
aes = "0.9"
|
||||||
|
|||||||
@@ -134,8 +134,9 @@ for the passphrase.
|
|||||||
|
|
||||||
## Network
|
## Network
|
||||||
|
|
||||||
Downloads verify TLS certificates (rustls with the platform verifier; it is
|
Downloads verify TLS certificates (rustls with the operating system's trust
|
||||||
never disabled), follow at most 10 redirects (http and https only; for
|
store; macOS binaries cross-built on Linux use the bundled Mozilla roots
|
||||||
|
instead, see `docs/PLATFORMS.md`; verification is never disabled), follow at most 10 redirects (http and https only; for
|
||||||
`mirror`, only to the same host), and are bounded by connect, response and
|
`mirror`, only to the same host), and are bounded by connect, response and
|
||||||
whole-request deadlines and a byte budget counted after decompression. See
|
whole-request deadlines and a byte budget counted after decompression. See
|
||||||
`vault(1)` for the defaults and flags.
|
`vault(1)` for the defaults and flags.
|
||||||
|
|||||||
@@ -14,7 +14,9 @@
|
|||||||
#
|
#
|
||||||
# How each target is built, and what the host needs:
|
# How each target is built, and what the host needs:
|
||||||
# zig cargo-zigbuild and zig on PATH (Linux, Windows GNU ABI)
|
# zig cargo-zigbuild and zig on PATH (Linux, Windows GNU ABI)
|
||||||
# mac a Mac with Xcode (macOS)
|
# mac a Mac with Xcode, or zig (macOS; zig builds trust the
|
||||||
|
# bundled Mozilla roots, not the
|
||||||
|
# keychain)
|
||||||
# cross `cross` and Docker (FreeBSD)
|
# cross `cross` and Docker (FreeBSD)
|
||||||
# A requested target the host cannot build is reported, the others are still
|
# A requested target the host cannot build is reported, the others are still
|
||||||
# built, and the script exits non-zero. See docs/PLATFORMS.md for the Go
|
# built, and the script exits non-zero. See docs/PLATFORMS.md for the Go
|
||||||
@@ -98,8 +100,16 @@ build_one() {
|
|||||||
{ echo "SKIPPED $want: needs cargo-zigbuild and zig" >&2; return 1; }
|
{ echo "SKIPPED $want: needs cargo-zigbuild and zig" >&2; return 1; }
|
||||||
cmd=(cargo zigbuild) ;;
|
cmd=(cargo zigbuild) ;;
|
||||||
mac)
|
mac)
|
||||||
[[ $HOST_OS == Darwin ]] || { echo "SKIPPED $want: needs a Mac with Xcode" >&2; return 1; }
|
if [[ $HOST_OS == Darwin ]]; then
|
||||||
cmd=(cargo build) ;;
|
cmd=(cargo build)
|
||||||
|
elif command -v cargo-zigbuild >/dev/null && command -v zig >/dev/null; then
|
||||||
|
# Without Apple's SDK there is no Security framework to link, so
|
||||||
|
# the cross-built binary trusts the bundled Mozilla roots rather
|
||||||
|
# than the macOS keychain.
|
||||||
|
cmd=(cargo zigbuild --no-default-features)
|
||||||
|
else
|
||||||
|
echo "SKIPPED $want: needs a Mac, or cargo-zigbuild and zig" >&2; return 1
|
||||||
|
fi ;;
|
||||||
cross)
|
cross)
|
||||||
command -v cross >/dev/null && command -v docker >/dev/null ||
|
command -v cross >/dev/null && command -v docker >/dev/null ||
|
||||||
{ echo "SKIPPED $want: needs cross and docker" >&2; return 1; }
|
{ echo "SKIPPED $want: needs cross and docker" >&2; return 1; }
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ the port: the Go release's more exotic targets are no longer built).
|
|||||||
| windows/amd64 | x86_64-pc-windows-gnu | static CRT | zig | build; tests cross-compile cleanly; runtime in CI only (windows-2025 job, not yet run) |
|
| windows/amd64 | x86_64-pc-windows-gnu | static CRT | zig | build; tests cross-compile cleanly; runtime in CI only (windows-2025 job, not yet run) |
|
||||||
| windows/386 | i686-pc-windows-gnu | static CRT | zig | build only |
|
| windows/386 | i686-pc-windows-gnu | static CRT | zig | build only |
|
||||||
| windows/arm64 | aarch64-pc-windows-gnullvm | static CRT | zig | build only |
|
| windows/arm64 | aarch64-pc-windows-gnullvm | static CRT | zig | build only |
|
||||||
| darwin/amd64 | x86_64-apple-darwin | system | a Mac (Xcode) | CI only (macos-15-intel job, not yet run) |
|
| darwin/amd64 | x86_64-apple-darwin | system | a Mac, or zig (note 2) | build only from Linux; tested in CI on macos-15-intel |
|
||||||
| darwin/arm64 | aarch64-apple-darwin | system | a Mac (Xcode) | CI only (macos-15 job, not yet run) |
|
| darwin/arm64 | aarch64-apple-darwin | system | a Mac, or zig (note 2) | build only from Linux; tested in CI on macos-15 |
|
||||||
| freebsd/amd64 | x86_64-unknown-freebsd | system | cross 0.2.5 (Docker) | build only (no emulator) |
|
| freebsd/amd64 | x86_64-unknown-freebsd | system | cross 0.2.5 (Docker) | build only (no emulator) |
|
||||||
| freebsd/386 | i686-unknown-freebsd | system | cross 0.2.5 (Docker) | build only |
|
| freebsd/386 | i686-unknown-freebsd | system | cross 0.2.5 (Docker) | build only |
|
||||||
|
|
||||||
@@ -47,6 +47,12 @@ disables core dumps. See `SECURITY.md`.
|
|||||||
process spins). `build.sh` and `packaging/package.sh` build that target
|
process spins). `build.sh` and `packaging/package.sh` build that target
|
||||||
with `--cfg getrandom_backend="linux_raw"`, which makes the `getrandom`
|
with `--cfg getrandom_backend="linux_raw"`, which makes the `getrandom`
|
||||||
crate issue the system call itself; with that flag the binary passes.
|
crate issue the system call itself; with that flag the binary passes.
|
||||||
|
2. Without Apple's SDK there is no Security framework to link, so `build.sh`
|
||||||
|
on Linux cross-builds macOS with `--no-default-features`: those binaries
|
||||||
|
verify TLS for `add URL` and `mirror` against the bundled Mozilla roots
|
||||||
|
instead of the macOS keychain (so a corporate CA added to the keychain is
|
||||||
|
not trusted). Built on a Mac, or through Homebrew
|
||||||
|
(`brew install andydixon/tap/vault`), they use the keychain.
|
||||||
|
|
||||||
## No longer released
|
## No longer released
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 525 KiB After Width: | Height: | Size: 604 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 195 KiB |
@@ -135,9 +135,14 @@ impl Client {
|
|||||||
Some(p) => Some(ureq::Proxy::new(p).map_err(|_| "invalid proxy setting in the environment".to_string())?),
|
Some(p) => Some(ureq::Proxy::new(p).map_err(|_| "invalid proxy setting in the environment".to_string())?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let tls = ureq::tls::TlsConfig::builder()
|
// The operating system's trust store; builds without the
|
||||||
.root_certs(ureq::tls::RootCerts::PlatformVerifier)
|
// `system-roots` feature (macOS binaries cross-built without
|
||||||
.build();
|
// Apple's SDK) use the bundled Mozilla roots instead.
|
||||||
|
#[cfg(feature = "system-roots")]
|
||||||
|
let roots = ureq::tls::RootCerts::PlatformVerifier;
|
||||||
|
#[cfg(not(feature = "system-roots"))]
|
||||||
|
let roots = ureq::tls::RootCerts::WebPki;
|
||||||
|
let tls = ureq::tls::TlsConfig::builder().root_certs(roots).build();
|
||||||
let l = &self.limits;
|
let l = &self.limits;
|
||||||
let cfg = ureq::Agent::config_builder()
|
let cfg = ureq::Agent::config_builder()
|
||||||
.tls_config(tls)
|
.tls_config(tls)
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ fn hold_lock(e: &Env, bin: &str) -> Child {
|
|||||||
c.stdin.as_mut().unwrap().write_all(b"\0").unwrap();
|
c.stdin.as_mut().unwrap().write_all(b"\0").unwrap();
|
||||||
// Wait until the lock file is held exclusively: probe with our own
|
// Wait until the lock file is held exclusively: probe with our own
|
||||||
// fcntl lock attempt from this process.
|
// fcntl lock attempt from this process.
|
||||||
let deadline = Instant::now() + Duration::from_secs(20);
|
let deadline = Instant::now() + Duration::from_secs(120);
|
||||||
loop {
|
loop {
|
||||||
if locked_exclusively(&e.dir.join("store/.lock")) {
|
if locked_exclusively(&e.dir.join("store/.lock")) {
|
||||||
return c;
|
return c;
|
||||||
@@ -350,13 +350,32 @@ fn lock_contention(holder: &str, waiter: &str) {
|
|||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
std::thread::sleep(Duration::from_millis(1500));
|
// Wait (however long unlocking takes on a busy machine) until the
|
||||||
|
// reader says it is blocked on the lock, and is still running.
|
||||||
|
let mut err = w.stderr.take().unwrap();
|
||||||
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
use std::io::Read;
|
||||||
|
let mut all = Vec::new();
|
||||||
|
let mut buf = [0u8; 256];
|
||||||
|
while let Ok(n) = err.read(&mut buf) {
|
||||||
|
if n == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
all.extend_from_slice(&buf[..n]);
|
||||||
|
if String::from_utf8_lossy(&all).contains("waiting for another vault process to finish") {
|
||||||
|
let _ = tx.send(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rx.recv_timeout(Duration::from_secs(120))
|
||||||
|
.expect("reader never reported waiting for the lock");
|
||||||
|
std::thread::sleep(Duration::from_millis(300));
|
||||||
assert!(w.try_wait().unwrap().is_none(), "reader did not wait for the writer");
|
assert!(w.try_wait().unwrap().is_none(), "reader did not wait for the writer");
|
||||||
h.kill().unwrap(); // death releases the lock
|
h.kill().unwrap(); // death releases the lock
|
||||||
let _ = h.wait();
|
let _ = h.wait();
|
||||||
let o = w.wait_with_output().unwrap();
|
let o = w.wait_with_output().unwrap();
|
||||||
assert!(o.status.success());
|
assert!(o.status.success(), "reader failed after the writer died");
|
||||||
assert!(String::from_utf8_lossy(&o.stderr).contains("waiting for another vault process to finish"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
|||||||