Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .github/workflows/agentless-container.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ on:
- containers/agentless/**
- .github/workflows/agentless-container.yaml

permissions:
contents: read

# NOTE: we may want to switch to matrix build for multi-platform support if this is taking too long
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/cli-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ on:
tags:
- cli/*

permissions:
contents: read

env:
# Opt all JS actions into Node 24 ahead of GitHub's Node 20 phase-out.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/commit-linting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ name: Commit Linting
on:
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]

permissions:
contents: read

jobs:
commit-linting:
name: Git commit linting
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/fern-docs-preview-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ on:
types: [completed]

permissions:
pull-requests: write
actions: read
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_repository.full_name || github.repository }}-${{ github.event.workflow_run.head_branch || github.event.workflow_run.id }}
Expand All @@ -44,6 +43,11 @@ jobs:
# runs-on: linux-amd64-cpu8 # NVIDIA self-hosted runner
timeout-minutes: 15
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
# Posts or updates the preview comment on the PR.
pull-requests: write
# Downloads the fern-preview artifact from the triggering build run.
actions: read
steps:
- name: Download fern sources and metadata
uses: actions/download-artifact@v8
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/lint-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ on:
branches:
- main

permissions:
contents: read

env:
# Opt all JS actions into Node 24 ahead of GitHub's Node 20 phase-out.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/operator-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ on:
- k8s-tests/**
- chart/**

permissions:
contents: read

## these envs control the build and test process below
env:
REGISTRY: ghcr.io
Expand Down Expand Up @@ -113,6 +116,11 @@ jobs:
tests:
runs-on: ubuntu-latest
needs: [k8s-test-versions]
permissions:
contents: read
# For the ghcr.io login below: the suites pull from ghcr.io and never
# push there (push-local-image targets the local ctlptl registry).
packages: read
strategy:
matrix:
# Standard E2E tests on all supported K8s versions
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/publish-fern-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ on:
# - "chart/v[0-9]*.[0-9]*.[0-9]*"

permissions:
contents: write
pull-requests: write
contents: read

concurrency:
group: fern-publish
Expand All @@ -91,6 +90,11 @@ jobs:
runs-on: ubuntu-latest
# runs-on: linux-amd64-cpu8 # NVIDIA self-hosted runner
timeout-minutes: 20
permissions:
# For create-pull-request: it pushes the registry branch and opens the
# PR that persists it to main.
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v7
Expand Down
20 changes: 18 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ on:
- 'agent/**'
- 'chart/**'

permissions:
contents: read

jobs:
release:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -193,7 +196,7 @@ jobs:
${PRERELEASE_FLAG}
fi

- name: Upload third-party notices to release
- name: Upload third-party notices and checksums to release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
Expand All @@ -207,7 +210,20 @@ jobs:
exit 1
;;
esac
gh release upload "${{ github.ref_name }}" "${NOTICES_FILE}" --clobber
if [[ ! -s "${NOTICES_FILE}" ]]; then
echo "ERROR: ${NOTICES_FILE} is missing or empty." >&2
exit 1
fi
# checksums.txt names each asset as the release does, by basename, so
# `sha256sum -c checksums.txt` works beside the downloads. Hashing that
# name here at the repo root would read the chart rollup on an operator
# or agent tag, so stage the exact file alone under its asset name and
# hash, verify and upload from there.
ASSET_DIR="$(mktemp -d)"
ASSET="$(basename "${NOTICES_FILE}")"
cp "${NOTICES_FILE}" "${ASSET_DIR}/${ASSET}"
( cd "${ASSET_DIR}" && sha256sum "${ASSET}" > checksums.txt && sha256sum -c --strict checksums.txt )
gh release upload "${{ github.ref_name }}" "${ASSET_DIR}/${ASSET}" "${ASSET_DIR}/checksums.txt" --clobber

publish-chart:
if: startsWith(github.ref_name, 'chart/')
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/security-checkov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ on:
paths:
- 'chart/**'

permissions:
contents: read

env:
# Opt all JS actions into Node 24 ahead of GitHub's Node 20 phase-out.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
Expand Down
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ Maintainers, decision-making, and the process for becoming a maintainer are docu
- **Questions**: Use [GitHub Discussions](https://github.com/NVIDIA/nodewright/discussions).
- **Security vulnerabilities**: Do **not** file a public issue. See [SECURITY.md](SECURITY.md).

### Issue priority

Maintainers communicate an issue's priority with its **Priority** field (Urgent / High / Medium / Low), which they set in the issue sidebar during triage. Priority is never a label, and reporters do not set it; the issue forms do not ask for it.

Critical bugs and security vulnerabilities are prioritized, as [SUPPORT.md](SUPPORT.md#what-to-expect) says. Report a security vulnerability through [SECURITY.md](SECURITY.md) rather than an issue.

If you think an issue's priority is wrong, comment on the issue with the context, such as its impact, and a maintainer decides.

## Claiming an Issue

Want to work on an issue? Claim it so others know it is taken. Comment on the issue and a bot will handle the assignment:
Expand Down
9 changes: 9 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NodeWright (formerly Skyhook)
Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.

This product includes software developed at
NVIDIA CORPORATION (https://www.nvidia.com/).

This project is licensed under the Apache License 2.0; see LICENSE.

Third-party components and their licenses are listed in THIRD_PARTY_NOTICES.md.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

**NodeWright** is a Kubernetes-aware package manager for cluster administrators to safely modify and maintain underlying host declaratively at scale.

**New here?** Start with the **[Quickstart](docs/getting-started/quickstart.md)** to install NodeWright and run a package on one node in about five minutes, or the **[Overview](docs/getting-started/overview.md)** for what NodeWright is and when to reach for it. Full docs live in [`docs/`](docs/README.md).
**New here?** Start with the **[Quickstart](docs/getting-started/quickstart.md)** to install NodeWright and run a package on one node in about five minutes, or the **[Overview](docs/getting-started/overview.md)** for what NodeWright is and when to reach for it. Full docs live in [`docs/`](docs/README.md) and are published at [docs.nvidia.com/nodewright](https://docs.nvidia.com/nodewright).

> **Note:** NodeWright is being renamed from Skyhook, and the rename has now landed for the core surfaces. The Helm chart, operator image, CLI (`kubectl nodewright`), and the CRDs (`nodewright.nvidia.com/v1alpha1`, Kind `NodeWright`; `DeploymentPolicy` moves to the same group) are published under `nodewright`. Existing `skyhook.nvidia.com`/`Skyhook` resources keep working during the transition: the operator auto-imports them to NodeWright and preserves per-node state (no package re-run), and legacy writes emit a deprecation warning. See the [migration guide](docs/getting-started/migration.md).
>
Expand Down
21 changes: 18 additions & 3 deletions agent/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ For the full commit-level log see CHANGELOG.md.
removed.** The next release is `agent/v7.0.0`; `agent/v6.x` images are the
Python agent and stay on GHCR. The operator-facing contract is unchanged:
positional arguments, environment variables, exit codes, and the flag,
history, interrupt-marker and log paths written on the host, as verified by
the operator-agent chainsaw suite that ran against both implementations
before the cutover. Both implementations honour each other's on-host state,
history, interrupt-marker and log directories written on the host, as
verified by the operator-agent chainsaw suite that ran against both
implementations before the cutover. Two log file names inside those
directories do change; see Behavior Changes. Both implementations honour
each other's on-host state,
so moving a node between `v6.x` and `v7.x` in either direction does not
re-run completed steps or interrupts, with the single `node_restart`
exception described under Upgrade and Rollback below.
Expand All @@ -30,6 +32,19 @@ For the full commit-level log see CHANGELOG.md.
timestamp.** Step and interrupt output is written to the log file as the
script produced it. Anything parsing those files for the prefix must stop
expecting it.
- **Step stderr lands in the same host log file as stdout, and log files are
mode 0600.** The Python agent wrote stdout to `<step>-<timestamp>.log` (0644)
and stderr to a sibling `<step>-<timestamp>.log.err`. Neither agent reaps the
zero-byte `.log.err` files a `v6.x` node already carries; remove them by hand
if the clutter matters.
- **Interrupt logs are one file per interrupt run, and are reaped.** The
directory is unchanged,
`<SKYHOOK_LOG_DIR>/<package name in the NodeWright>/<version>/interrupts/`,
but the file is now `<type>-<timestamp>.log` for the whole interrupt, kept to
the newest five like step logs. The Python agent wrote
`<type>_<index>-<timestamp>.log` per operation and never removed any; those
names do not match the new reaping pattern, so they stay on a `v6.x` node
until removed by hand.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- **`SKYHOOK_AGENT_BUFFER_LIMIT` is no longer read or printed.** It only tuned
the Python agent's stream reader and had no equivalent in Go.
- **The CycloneDX SBOM moved from the multi-platform index digest to each platform manifest digest, and an OpenVEX document is now published alongside it.** An SBOM describes exactly one root filesystem, so one attached to a multi-platform index described neither child truthfully, and a consumer who resolved `linux/amd64` and enumerated referrers on that manifest found nothing.
Expand Down
11 changes: 9 additions & 2 deletions docs/architecture/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,15 @@ Deleting a NodeWright does not delete the changes it made to your hosts. The
operator:

1. Runs the uninstall workflow for every package with `uninstall.enabled: true`
2. Cleans its metadata off the nodes — state annotations, cordons it owns, and
the runtime-required taint
2. Cleans its metadata off the nodes — the status labels, annotations and
conditions it owns, and the cordons it holds. The `nodeState_<name>` and
`version_<name>` annotations are kept as long as they still record packages
whose files remain on the host (a non-absent entry means "installed"; see
[CR Deletion in the uninstall guide](../user-guide/uninstall.md#cr-deletion-finalizer)),
and removed once nothing remains.
The runtime-required taint is not touched here; only the completion path in
[runtime-required](../user-guide/runtime-required.md#when-is-the-runtime-required-taint-removed-from-a-node)
removes it.
3. Releases the finalizer, at which point the object disappears

Packages without `uninstall.enabled` are simply forgotten, not reversed. Their
Expand Down
Loading
Loading