Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 49 additions & 21 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14945,7 +14945,7 @@ on the way back up, so a crash mid-write reclaims itself.
| Symptom | Cause | Fix |
| --- | --- | --- |
| Unit restarts in a loop, journal says `unknown field` | Config is parsed with `deny_unknown_fields`; one unrecognised key is fatal | Check the key in the [configuration reference](/reference/nativelink-config) |
| Process exits during startup, no error about ports | `NL_OTEL_ENDPOINT` without a scheme or explicit port panics before binding | Use `http://host:4317`; see [CLI and environment](/reference/cli-and-env) |
| Process exits during startup, no error about ports | `NL_OTEL_ENDPOINT` without a scheme or explicit port stops the process before binding | Use `http://host:4317`; see [CLI and environment](/reference/cli-and-env) |
| Everything slows down under load, nothing errors | File-descriptor semaphore exhaustion blocks rather than failing | Raise `LimitNOFILE` **and** `max_open_files` together |
| Two workers on one host behave erratically | They share a `work_directory`, which is purged at startup | Give each worker its own |
| Disk full, then every request fails and keeps retrying | ENOSPC surfaces as a generic error code that clients and upstream stores retry, and eviction is not triggered by write failures | [Runbooks](/operate/runbooks#the-disk-fills-up) |
Expand Down Expand Up @@ -15033,12 +15033,12 @@ export RUST_LOG=info
<Callout type="warn" title="NL_OTEL_ENDPOINT needs a scheme and an explicit port">

The value is parsed as a URL and the host and port are pulled out
individually, and each step `unwrap`s. A value with no scheme, or with no
explicit port, yields `None` for the port and **panics the process during
startup**, before it binds a socket.
individually. A value with no scheme, or with no explicit port, **stops the
process during startup** with an error, before it binds a socket, rather
than falling back to a default.

`http://otel-collector:4317` is correct. `otel-collector:4317` and
`http://otel-collector` both crash the binary.
`http://otel-collector` both stop the binary.

</Callout>

Expand All @@ -15051,12 +15051,28 @@ a cluster, because it re-resolves the collector's DNS as pods move. Either way
the transport is OTLP over gRPC: the binary is built with only the gRPC
exporter, so `OTEL_EXPORTER_OTLP_PROTOCOL` cannot switch it to HTTP.

An `https://` endpoint, in either variable, gets TLS. Without further
configuration the collector's certificate is checked against the host's
system trust store, which is what you want for a collector behind a
public certificate. For a collector with a private CA, set
`OTEL_EXPORTER_OTLP_CERTIFICATE` to the PEM file of that CA and only it is
trusted. For a collector that asks the client for a certificate (mTLS), set
`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` and `OTEL_EXPORTER_OTLP_CLIENT_KEY`
together. These are the OpenTelemetry specification's own variable names,
so a worker outside the cluster (a macOS worker, say) reaches the cluster's
collector with the same configuration any other OTLP client would use. The
per-signal forms (`OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` and so on) win over
the general one, as the specification says.

The rest of the surface is small enough to state in full:

| Variable | Default | What it does here |
| --- | --- | --- |
| `NL_OTEL_ENDPOINT` | unset | One shared gRPC channel for logs, traces and metrics. Panics on a malformed value. |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4317` | Used only when `NL_OTEL_ENDPOINT` is unset. |
| `NL_OTEL_ENDPOINT` | unset | One shared gRPC channel for logs, traces and metrics. Stops the process on a malformed value. An `https://` value gets TLS; a per-signal certificate variable gives that signal a channel of its own, built with its material. |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4317` | Used only when `NL_OTEL_ENDPOINT` is unset. An `https://` value gets TLS. |
| `OTEL_EXPORTER_OTLP_CERTIFICATE` | unset | Path to the PEM CA that signs the collector's certificate. Set, it is the only CA trusted; unset, the system trust store is. |
| `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` | unset | Path to the PEM certificate the exporter presents to the collector for mTLS. Requires `OTEL_EXPORTER_OTLP_CLIENT_KEY`; one without the other stops the process. |
| `OTEL_EXPORTER_OTLP_CLIENT_KEY` | unset | Path to the PEM private key for that certificate. |
| `OTEL_EXPORTER_OTLP_COMPRESSION` | unset | `gzip` or `zstd` on the gRPC exporters; the shipped Kubernetes manifests set `zstd`. |
| `OTEL_METRIC_EXPORT_INTERVAL` | `60000` (ms) | How often metrics flush. NativeLink sets no interval, so the SDK default of one minute applies. This is the first hop in the [reaction-time budget](/operate/autoscaling-reference#the-reaction-time-budget); lower it to 10000 before you scale on anything. |
| `RUST_LOG` | `info` | Applies to the stdout layer **and** to all three OTLP layers. `hyper`, `tonic`, `h2`, `reqwest` and `tower` are forced off afterwards and cannot be re-enabled. |
Expand Down Expand Up @@ -15426,7 +15442,8 @@ not your pipeline.

| Symptom | Cause | Fix |
| --- | --- | --- |
| Process panics at startup with a URL error | `NL_OTEL_ENDPOINT` has no scheme or no explicit port | Use `http://host:4317` |
| Process stops at startup with a URL error | `NL_OTEL_ENDPOINT` has no scheme or no explicit port | Use `http://host:4317` |
| Process stops at startup naming an `OTEL_EXPORTER_OTLP_*` variable | A certificate variable names a file the process cannot read, or a client certificate is set without its key | Fix the path, or set `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` and `OTEL_EXPORTER_OTLP_CLIENT_KEY` together |
| No metrics anywhere, process healthy | Nothing is pushing; check `otelcol_receiver_accepted_metric_points` on `:8888` | Verify the endpoint and that it is set on the process you are looking for |
| Metrics appear a minute late | `OTEL_METRIC_EXPORT_INTERVAL` defaults to 60 s | Set `10000` |
| `nativelink_execution_*` present, `nativelink_cache_*` missing | No store is wrapped | [Turn on cache metrics](#turn-on-cache-metrics) |
Expand Down Expand Up @@ -15806,10 +15823,13 @@ run on your behalf.
What the worker actually does before executing an action:

```text
unshare(CLONE_NEWPID | CLONE_NEWUSER | CLONE_NEWIPC | CLONE_NEWUTS)
unshare(CLONE_NEWPID | CLONE_NEWUSER | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_NEWNS)
write /proc/self/setgroups "deny"
write /proc/self/uid_map "<uid> <uid> 1"
write /proc/self/gid_map "<gid> <gid> 1"
mount --make-rprivate /
fork # the child is PID 1 of the new PID namespace
mount -t proc proc /proc # in that child, so /proc lists the action's processes
```

<SourceLink file="nativelink-worker/src/namespace_utils.rs" symbol="unshare" />
Expand All @@ -15818,10 +15838,15 @@ Read the uid map carefully. It is an **identity** map: uid *N* inside the
namespace is uid *N* outside it. The action runs as the worker's own user, with
the worker's own privileges on the host filesystem. This is not a
uid-remapping sandbox; it is a process-reaping and hermeticity mechanism. PID
namespacing means orphaned children die with the action instead of leaking;
IPC and UTS namespacing means actions cannot see each other's semaphores or
hostname (the hostname is set to `nativelink`). With `use_mount_namespace`
the flag list also gains `CLONE_NEWNS`, the worker's own root action
namespacing means orphaned children die with the action instead of leaking,
and the fresh `/proc` means what an action finds there is its own processes,
each under the PID the action knows it by (where the host refuses that mount, as an
unprivileged container that masks paths under `/proc` does, the worker warns
at startup and the action sees the host's `/proc`); IPC and UTS namespacing
means actions cannot see each other's semaphores or hostname (the hostname is
set to `nativelink`). The mount namespace is private to the action, so the
`/proc` mount never reaches the host; without `use_mount_namespace` nothing
else in it changes. With `use_mount_namespace` the worker's own root action
directory is masked so one action cannot see another's tree, and `/tmp` is
replaced with the action's own temporary directory, on the worker's disk and
removed with the action, so actions cannot collide on, or leak state
Expand Down Expand Up @@ -21038,20 +21063,23 @@ They are the only variables that change the binary's own behaviour.
| Variable | Default | Effect |
| --- | --- | --- |
| `NL_LOG` | `pretty` | Format of the stdout log layer. `compact` and `json` are recognised; **any other value silently falls back to `pretty`**, including a typo like `Json`. |
| `RUST_LOG` | `info` | Log filter, parsed by `tracing_subscriber`'s `EnvFilter` in lossy mode; an unparseable directive is dropped rather than fatal. Applies to the stdout layer *and* to the OTLP log, trace and metric layers. `hyper`, `tonic`, `h2`, `reqwest` and `tower` are forced off afterwards and cannot be re-enabled from here. |
| `NL_OTEL_ENDPOINT` | not set | When set, all three OTLP exporters share one client-side load-balanced gRPC channel pointed at this endpoint. When unset, each exporter is built with the SDK's own tonic defaults instead. |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4317` | Standard OpenTelemetry SDK variable. Applies only when `NL_OTEL_ENDPOINT` is unset; an explicit channel wins over the SDK's endpoint resolution. The signal-specific `OTEL_EXPORTER_OTLP_{LOGS,TRACES,METRICS}_ENDPOINT` variables behave the same way. |
| `RUST_LOG` | `info` | Log filter, parsed by `tracing_subscriber`'s `EnvFilter` in lossy mode; a directive that cannot be parsed is dropped rather than fatal. Applies to the stdout layer *and* to the OTLP log, trace and metric layers. `hyper`, `tonic`, `h2`, `reqwest` and `tower` are forced off afterwards and cannot be re-enabled from here. |
| `NL_OTEL_ENDPOINT` | not set | When set, all three OTLP exporters share one client-side load-balanced gRPC channel pointed at this endpoint. When unset, each exporter is built with the SDK's own tonic defaults instead. An `https://` endpoint gets TLS, with the certificate variables below or the system trust store. A per-signal certificate variable gives that signal a channel of its own, built with its material, instead of the shared one. |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4317` | Standard OpenTelemetry SDK variable. Applies only when `NL_OTEL_ENDPOINT` is unset; an explicit channel wins over the SDK's endpoint resolution. The signal-specific `OTEL_EXPORTER_OTLP_{LOGS,TRACES,METRICS}_ENDPOINT` variables behave the same way. An `https://` endpoint gets TLS, with the certificate variables below or the system trust store. |
| `OTEL_EXPORTER_OTLP_CERTIFICATE` | not set | Standard OpenTelemetry variable, read by NativeLink itself because the Rust SDK does not: the path to a PEM file holding the CA that signs the collector's certificate. Set, it is the only CA trusted; unset, the host's system trust store is. The signal-specific `OTEL_EXPORTER_OTLP_{LOGS,TRACES,METRICS}_CERTIFICATE` forms win over it. An empty value counts as unset; a path that cannot be read stops the process at startup. |
| `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` | not set | The path to the PEM certificate the exporter presents when the collector asks for one (mTLS). Has to be set together with `OTEL_EXPORTER_OTLP_CLIENT_KEY`; one without the other stops the process at startup. Signal-specific forms as above. |
| `OTEL_EXPORTER_OTLP_CLIENT_KEY` | not set | The path to the PEM private key for `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE`. Signal-specific forms as above. |
| `OTEL_METRIC_EXPORT_INTERVAL` | `60000` (ms) | How often the periodic metric reader flushes to the collector. NativeLink sets no interval of its own, so the SDK default of one minute applies unless you override it here. This is the first hop in the [reaction-time budget](/operate/autoscaling-reference). |

<Callout type="warn" title="NL_OTEL_ENDPOINT requires a scheme and an explicit port">

The endpoint is parsed as a URL and then the host and port are pulled out
individually, and each step `unwrap`s. A value with no scheme, or with no
explicit port, yields `None` for the port and **panics the process during
startup** rather than falling back to a default.
individually. A value with no scheme, or with no explicit port, **stops the
process during startup** with an error rather than falling back to a
default.

`http://otel-collector:4317` is correct. `otel-collector:4317` and
`http://otel-collector` both crash the binary before it binds a socket.
`http://otel-collector` both stop the binary before it binds a socket.

</Callout>

Expand Down Expand Up @@ -21957,7 +21985,7 @@ Bazel.
## Prerequisites [#prerequisites]

- Bazelisk, which reads `.bazelversion` and fetches the right Bazel for
you. CI runs 9.1.1 and also checks 8.7.0.
you. CI runs 9.3.1 and also checks 8.8.2.
- A C++ toolchain (clang or gcc) for native dependencies.
- On macOS: XCode command-line tools.
- On Linux, inside the Nix shell, the LRE toolchains link with `mold`;
Expand Down
2 changes: 1 addition & 1 deletion llms-small.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4851,7 +4851,7 @@ Bazel.
## Prerequisites

- Bazelisk, which reads `.bazelversion` and fetches the right Bazel for
you. CI runs 9.1.1 and also checks 8.7.0.
you. CI runs 9.3.1 and also checks 8.8.2.
- A C++ toolchain (clang or gcc) for native dependencies.
- On macOS: XCode command-line tools.
- On Linux, inside the Nix shell, the LRE toolchains link with `mold`;
Expand Down