diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5bb3f5fda..56786b789 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,4 @@ +# ref: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "github-actions" @@ -6,6 +7,8 @@ updates: schedule: interval: "monthly" groups: - github-actions-update: + github-actions-updates: patterns: - "*" + cooldown: + default-days: 14 diff --git a/.github/workflows/build-images.yaml b/.github/workflows/build-images.yaml index 2f9756203..57332ca50 100644 --- a/.github/workflows/build-images.yaml +++ b/.github/workflows/build-images.yaml @@ -40,11 +40,11 @@ jobs: sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android df -h - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login registry if: ${{ inputs.push == 'true' }} run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin diff --git a/.github/workflows/create-chart-update-pr.yaml b/.github/workflows/create-chart-update-pr.yaml index 651beedf8..80004e378 100644 --- a/.github/workflows/create-chart-update-pr.yaml +++ b/.github/workflows/create-chart-update-pr.yaml @@ -10,6 +10,9 @@ on: description: chart version (e.g. 0.1.0) type: string +permissions: + contents: write + jobs: create-chart-update-pr: runs-on: "ubuntu-latest" @@ -19,7 +22,7 @@ jobs: # The exit code will be 1 if the pattern is not found by grep. echo ${{ inputs.app-version }} | grep -E "^[0-9]+.[0-9]+.[0-9]+$" echo ${{ inputs.chart-version }} | grep -E "^[0-9]+.[0-9]+.[0-9]+$" - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: fetch-depth: 0 - name: Configure Git @@ -41,7 +44,7 @@ jobs: sed -r -i "s/ghcr.io\/topolvm\/topolvm:[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/ghcr.io\/topolvm\/topolvm:${{ inputs.app-version }}/g" charts/topolvm/Chart.yaml make install-helm-docs && make generate-helm-docs - name: Issue an access token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@v3 id: app-token with: app-id: ${{ secrets.PROJECT_APP_ID }} diff --git a/.github/workflows/e2e-k8s-incluster-lvmd.yaml b/.github/workflows/e2e-k8s-incluster-lvmd.yaml index 5e858da7e..336c34afd 100644 --- a/.github/workflows/e2e-k8s-incluster-lvmd.yaml +++ b/.github/workflows/e2e-k8s-incluster-lvmd.yaml @@ -10,6 +10,10 @@ on: - "CODEOWNERS" branches: - "main" + +permissions: + contents: read + jobs: e2e-k8s-incluster-lvmd: name: "e2e-k8s-incluster-lvmd" @@ -17,21 +21,21 @@ jobs: strategy: fail-fast: false matrix: - kubernetes_versions: ["1.34.3", "1.33.7", "1.32.11"] + kubernetes_versions: ["1.35.4", "1.34.3", "1.33.7"] test_lvmd_type: ["daemonset", "embedded"] env: KUBERNETES_VERSION: ${{ matrix.kubernetes_versions }} TEST_LVMD_TYPE: ${{ matrix.test_lvmd_type }} TEST_SCHEDULER_EXTENDER_TYPE: "none" steps: - - uses: actions/checkout@v6 - - uses: actions/setup-go@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: cache e2e sidecar binaries - uses: actions/cache@v5 + uses: actions/cache@v5.0.5 with: path: | test/e2e/tmpbin diff --git a/.github/workflows/e2e-k8s-workflow.yaml b/.github/workflows/e2e-k8s-workflow.yaml index 21147fe7a..e3e21e877 100644 --- a/.github/workflows/e2e-k8s-workflow.yaml +++ b/.github/workflows/e2e-k8s-workflow.yaml @@ -6,6 +6,9 @@ on: test_legacy: type: string +permissions: + contents: read + jobs: e2e-k8s: name: "e2e-k8s" @@ -13,38 +16,23 @@ jobs: strategy: fail-fast: false matrix: - kubernetes_versions: ["1.34.3", "1.33.7", "1.32.11"] + kubernetes_versions: ["1.35.4", "1.34.3", "1.33.7"] env: KUBERNETES_VERSION: ${{ matrix.kubernetes_versions }} TEST_SCHEDULER_EXTENDER_TYPE: ${{ inputs.test_scheduler_extender_type }} TEST_LEGACY: ${{ inputs.test_legacy }} steps: - - id: check - run: | - KUBERNETES_MINOR=$(echo "${{ matrix.kubernetes_versions }}" | cut -d'.' -f2) - if [ "$KUBERNETES_MINOR" -le 32 ] && [ "$TEST_SCHEDULER_EXTENDER_TYPE" = "none" ]; then - echo "Skipping test for Kubernetes version ${{ matrix.kubernetes_versions }} with scheduler extender type 'none'" - echo "should_run=false" >> $GITHUB_OUTPUT - else - echo "should_run=true" >> $GITHUB_OUTPUT - fi - - if: steps.check.outputs.should_run == 'true' - uses: actions/checkout@v6 - - if: steps.check.outputs.should_run == 'true' - uses: actions/setup-go@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" - - if: steps.check.outputs.should_run == 'true' - uses: actions/cache/restore@v5 + - uses: actions/cache/restore@v5.0.5 with: path: | bin test/e2e/bin test/e2e/topolvm.img key: e2e-cache-${{ github.sha }} - - if: steps.check.outputs.should_run == 'true' - run: touch test/e2e/topolvm.img # update timestamp not to rebuild image - - if: steps.check.outputs.should_run == 'true' - run: make -C test/e2e start-lvmd - - if: steps.check.outputs.should_run == 'true' - run: make -C test/e2e test + - run: touch test/e2e/topolvm.img # update timestamp not to rebuild image + - run: make -C test/e2e start-lvmd + - run: make -C test/e2e test diff --git a/.github/workflows/e2e-k8s.yaml b/.github/workflows/e2e-k8s.yaml index 447f67c00..c56b17d58 100644 --- a/.github/workflows/e2e-k8s.yaml +++ b/.github/workflows/e2e-k8s.yaml @@ -11,18 +11,21 @@ on: branches: - "main" +permissions: + contents: read + jobs: build: runs-on: "ubuntu-22.04" steps: - - uses: actions/checkout@v6 - - uses: actions/setup-go@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: cache e2e sidecar binaries - uses: actions/cache@v5 + uses: actions/cache@v5.0.5 with: path: | test/e2e/tmpbin @@ -31,7 +34,7 @@ jobs: e2e-sidecars- - run: make -C test/e2e setup - run: make -C test/e2e topolvm.img - - uses: actions/cache/save@v5 + - uses: actions/cache/save@v5.0.5 with: path: | bin diff --git a/.github/workflows/helm-release.yaml b/.github/workflows/helm-release.yaml index b85e6b7d7..99aa6566f 100644 --- a/.github/workflows/helm-release.yaml +++ b/.github/workflows/helm-release.yaml @@ -2,12 +2,15 @@ name: "Release Charts" on: "workflow_dispatch" +permissions: + contents: write + jobs: release: runs-on: "ubuntu-latest" steps: - name: "Checkout" - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: fetch-depth: 0 @@ -19,7 +22,7 @@ jobs: # This version is written in `charts/topolvm/README.md`, # so do not update it if not necessary. - name: "Install Helm" - uses: azure/setup-helm@v4 + uses: azure/setup-helm@v5 with: version: "v3.5.0" diff --git a/.github/workflows/helm.yaml b/.github/workflows/helm.yaml index b7bea8af8..18b1176bd 100644 --- a/.github/workflows/helm.yaml +++ b/.github/workflows/helm.yaml @@ -6,18 +6,21 @@ on: - "charts/**" - "ct.yaml" +permissions: + contents: read + jobs: lint: runs-on: "ubuntu-22.04" steps: - name: "Checkout" - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: fetch-depth: 0 - name: "Setup Go" - uses: actions/setup-go@v6 + uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index f3800b1e4..a9e4196c3 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -4,19 +4,24 @@ on: push: branches: - "main" + +permissions: + contents: read + jobs: build: name: "build" runs-on: "ubuntu-22.04" steps: - - uses: actions/checkout@v6 - - uses: actions/setup-go@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - run: make setup - run: make check-uncommitted + - run: make test - run: make build-topolvm GOARCH=s390x name: "Build TopoLVM for s390x architecture" - run: make groupname-test @@ -38,9 +43,9 @@ jobs: - "normal" - "with-sidecar" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - run: make install-container-structure-test - run: make image-${{ matrix.image }} - run: make container-structure-test STRUCTURE_TEST_TARGET=${{ matrix.image }} @@ -53,11 +58,11 @@ jobs: run: working-directory: "example" steps: - - uses: actions/checkout@v6 - - uses: actions/setup-go@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - run: make setup - run: make run diff --git a/.github/workflows/pr-labeled.yaml b/.github/workflows/pr-labeled.yaml index f61ef9329..9012657c8 100644 --- a/.github/workflows/pr-labeled.yaml +++ b/.github/workflows/pr-labeled.yaml @@ -4,6 +4,8 @@ on: pull_request: types: [synchronize, opened, reopened, labeled, unlabeled] +permissions: {} + jobs: label-do-not-merge: runs-on: ubuntu-latest diff --git a/.github/workflows/project-bot.yaml b/.github/workflows/project-bot.yaml deleted file mode 100644 index fc3eae1c9..000000000 --- a/.github/workflows/project-bot.yaml +++ /dev/null @@ -1,50 +0,0 @@ -name: Add a new item to project -on: - issues: - types: - - opened - pull_request_target: - types: - - opened -jobs: - add_item: - runs-on: ubuntu-latest - steps: - - name: Issue an access token - uses: actions/create-github-app-token@v2 - id: app-token - with: - app-id: ${{ secrets.PROJECT_APP_ID }} - private-key: ${{ secrets.PROJECT_APP_PEM }} - - name: Get project data - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - ORGANIZATION: topolvm - PROJECT_NUMBER: "2" - run: | - proj_id="$(gh api graphql -f query=' - query($org: String!, $number: Int!) { - organization(login: $org){ - projectV2(number: $number) { - id - } - } - }' -F org=$ORGANIZATION -F number=$PROJECT_NUMBER --jq '.data.organization.projectV2.id')" - echo "PROJECT_ID=${proj_id}" >> $GITHUB_ENV - - name: Add an item to project - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - if [ ${{ github.event_name }} = issues ]; then - CONTENT_ID=${{ github.event.issue.node_id }} - else - CONTENT_ID=${{ github.event.pull_request.node_id }} - fi - gh api graphql -f query=' - mutation($project:ID!, $contentId:ID!) { - addProjectV2ItemById(input: {projectId: $project, contentId: $contentId}) { - item { - id - } - } - }' -F project=$PROJECT_ID -F contentId=$CONTENT_ID --jq '.data.addProjectV2ItemById.item.id' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b5eb162e9..9bd92479e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -3,6 +3,11 @@ on: push: tags: - "v*" + +permissions: + contents: write + packages: write + jobs: prepare: name: "prepare" @@ -44,12 +49,12 @@ jobs: needs: [prepare, build-images] runs-on: "ubuntu-22.04" steps: - - uses: actions/checkout@v6 - - uses: actions/setup-go@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v6.4.0 with: go-version-file: "go.mod" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - run: make build/lvmd TOPOLVM_VERSION=${{ needs.prepare.outputs.version }} - run: tar czf lvmd-${{ needs.prepare.outputs.version }}.tar.gz -C ./build lvmd - name: "Push branch tag" diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 104a82e79..24c88fe8b 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -12,13 +12,13 @@ on: jobs: stale: - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: issues: write pull-requests: write steps: - - uses: actions/stale@v10 + - uses: actions/stale@v10.3.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 30 @@ -42,4 +42,3 @@ jobs: stale-pr-label: "stale" exempt-issue-labels: "keepalive,update kubernetes" exempt-pr-labels: "keepalive" - exempt-draft-pr: true diff --git a/README.md b/README.md index 23cd86485..91458dce6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It can be considered as a specific implementation of [local persistent volumes]( Our supported platform are: -- Kubernetes: 1.34, 1.33, 1.32 +- Kubernetes: 1.35, 1.34, 1.33 - Node OS: Linux with LVM2 (\*1), specifically tested on Ubuntu - CPU Architecture: x86 (\*2), arm64 (\*3), ppc64le (\*3), s390x (\*4) - Filesystems: ext4, xfs, btrfs @@ -22,7 +22,7 @@ Our supported platform are: \*1 The host's Linux Kernel must be v4.9 or later which supports `rmapbt` and `reflink`, if you use xfs filesystem with an official docker image. \*2 Tier1 support. The official docker images are provided and all functionalities are tested by CI. \*3 Tier2 support. The official docker images are provided, but no tests run by CI. -\*4 Tier3 support. No docker images are provided, and no tests run by CI, but binaries are built. +\*4 Tier3 support. No docker images are provided, and no tests run by CI, but binaries are built. Docker images are available on [ghcr.io](https://github.com/orgs/topolvm/packages). diff --git a/RELEASE.md b/RELEASE.md index d770e7cff..694a728b5 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -45,9 +45,11 @@ Bump version VERSION=1.2.3 ``` -2. Go to [the rule setting page](https://github.com/topolvm/topolvm/settings/rules/2151135) and change the value of "Enforcement status" to `Active`. +2. Go to the rule [prevent changes to the main branch][] and change the value of "Enforcement status" to `Active`. -3. Add a new tag and push it. +3. Go to the rule [block tag creation][] and change the value of "Enforcement status" to `Disabled`. + +4. Add a new tag and push it. ```console git switch main @@ -56,7 +58,7 @@ Bump version git push origin v$VERSION ``` -4. Once a new tag is pushed, [GitHub Actions][] automatically +5. Once a new tag is pushed, [GitHub Actions][] automatically creates a draft release note for the tagged version, builds a tar archive for the new release, and attaches it to the release note. @@ -64,7 +66,7 @@ Bump version Visit https://github.com/topolvm/topolvm/releases to check the result. -5. Edit the auto-generated release note +6. Edit the auto-generated release note and remove PRs which contain changes only to the helm chart. Then, publish it. @@ -74,7 +76,7 @@ Bump Chart Version TopoLVM Helm Chart will be released independently. This will prevent the TopoLVM version from going up just by modifying the Helm Chart. -1. If necessary, go to [the rule setting page](https://github.com/topolvm/topolvm/settings/rules/2151135) and change the value of "Enforcement status" to `Active`. +1. If necessary, go to the rule [prevent changes to the main branch][] and change the value of "Enforcement status" to `Active`. - If you are here after releasing the app, you should already have this setting changed. 2. Determine a new version number by [checking the differences](https://github.com/topolvm/topolvm/compare/topolvm-chart-vX.Y.Z...main) since the last release. Then, manually run the workflow to create a PR to update the Helm Chart. @@ -82,10 +84,12 @@ This will prevent the TopoLVM version from going up just by modifying the Helm C https://github.com/topolvm/topolvm/actions/workflows/create-chart-update-pr.yaml 3. Review and merge the auto-created PR. - - Before merging, go to [the rule setting page](https://github.com/topolvm/topolvm/settings/rules/2151135) and change the value of "Enforcement status" to `Disabled`. + - Before merging, go to the rule [prevent changes to the main branch][] and change the value of "Enforcement status" to `Disabled`. 4. Manually run the GitHub Actions workflow for the release. + Before running the workflow, go to the rule [block tag creation][] and change the value of "Enforcement status" to `Disabled`. + https://github.com/topolvm/topolvm/actions/workflows/helm-release.yaml When you run workflow, [helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) will automatically create a GitHub Release. @@ -95,6 +99,9 @@ This will prevent the TopoLVM version from going up just by modifying the Helm C 2. Clear the textbox, and click "Generate release notes" button. 3. Remove PRs which do not contain changes to the helm chart. +6. Go to the rule [block tag creation][] and change the value of "Enforcement status" to `Active`. + [semver]: https://semver.org/spec/v2.0.0.html -[example]: https://github.com/cybozu-go/etcdpasswd/commit/77d95384ac6c97e7f48281eaf23cb94f68867f79 [GitHub Actions]: https://github.com/topolvm/topolvm/actions +[prevent changes to the main branch]: https://github.com/topolvm/topolvm/settings/rules/2151135 +[block tag creation]: https://github.com/topolvm/topolvm/settings/rules/17382112 diff --git a/charts/topolvm/Chart.yaml b/charts/topolvm/Chart.yaml index 0c511248e..0f3822a33 100644 --- a/charts/topolvm/Chart.yaml +++ b/charts/topolvm/Chart.yaml @@ -4,8 +4,8 @@ type: application home: https://github.com/topolvm/topolvm name: topolvm description: Topolvm -version: 16.0.0 -appVersion: 0.40.1 +version: 16.1.1 +appVersion: 0.41.0 sources: - https://github.com/topolvm/topolvm @@ -18,7 +18,7 @@ dependencies: annotations: artifacthub.io/images: | - name: topolvm-with-sidecar - image: ghcr.io/topolvm/topolvm-with-sidecar:0.40.1 + image: ghcr.io/topolvm/topolvm-with-sidecar:0.41.0 - name: topolvm-with - image: ghcr.io/topolvm/topolvm:0.40.1 + image: ghcr.io/topolvm/topolvm:0.41.0 artifacthub.io/license: Apache-2.0 diff --git a/charts/topolvm/README.md b/charts/topolvm/README.md index e278ffec8..b9f689037 100644 --- a/charts/topolvm/README.md +++ b/charts/topolvm/README.md @@ -7,7 +7,7 @@ ## Installation -See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v16.0.0/docs/getting-started.md). +See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v16.1.1/docs/getting-started.md). ## Values diff --git a/charts/topolvm/templates/controller/clusterroles.yaml b/charts/topolvm/templates/controller/clusterroles.yaml index f7e41706b..1ce7215a3 100644 --- a/charts/topolvm/templates/controller/clusterroles.yaml +++ b/charts/topolvm/templates/controller/clusterroles.yaml @@ -90,9 +90,14 @@ rules: - apiGroups: [""] resources: ["events"] verbs: ["list", "watch", "create", "update", "patch"] + # The "watch" and "update" verbs for volumesnapshots are optional but recommended. + # They enable finalizer-based protection to prevent snapshots from being deleted + # during provisioning. Without these permissions, the provisioner will still function + # but snapshot protection will be unavailable. This makes the provisioner backwards + # compatible with older RBAC configurations. - apiGroups: ["snapshot.storage.k8s.io"] resources: ["volumesnapshots"] - verbs: ["get", "list"] + verbs: ["get", "list", "watch", "update"] - apiGroups: ["snapshot.storage.k8s.io"] resources: ["volumesnapshotcontents"] verbs: ["get", "list"] @@ -145,7 +150,6 @@ rules: - apiGroups: [""] resources: ["events"] verbs: ["list", "watch", "create", "update", "patch"] - # only required if enabling the alpha volume modify feature - apiGroups: ["storage.k8s.io"] resources: ["volumeattributesclasses"] verbs: ["get", "list", "watch"] diff --git a/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml b/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml index fc3f8957d..fe67c2ae9 100644 --- a/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml +++ b/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.1 name: logicalvolumes.topolvm.cybozu.com spec: group: topolvm.cybozu.com diff --git a/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml b/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml index 11910b564..44d56c7bb 100644 --- a/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml +++ b/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.1 name: logicalvolumes.topolvm.io spec: group: topolvm.io diff --git a/charts/topolvm/templates/node/daemonset.yaml b/charts/topolvm/templates/node/daemonset.yaml index 21e8b14dd..6713eefc9 100644 --- a/charts/topolvm/templates/node/daemonset.yaml +++ b/charts/topolvm/templates/node/daemonset.yaml @@ -243,7 +243,7 @@ spec: - name: lvmd-socket-dir hostPath: path: {{ dir .Values.node.lvmdSocket }} - type: Directory + type: DirectoryOrCreate {{- end }} {{- end }} {{- with .Values.node.additionalVolumes }} diff --git a/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml b/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml index faf193e70..98d094c8c 100644 --- a/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml +++ b/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.1 name: logicalvolumes.topolvm.cybozu.com spec: group: topolvm.cybozu.com diff --git a/config/crd/bases/topolvm.io_logicalvolumes.yaml b/config/crd/bases/topolvm.io_logicalvolumes.yaml index f34b51c59..b3d56b960 100644 --- a/config/crd/bases/topolvm.io_logicalvolumes.yaml +++ b/config/crd/bases/topolvm.io_logicalvolumes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.1 name: logicalvolumes.topolvm.io spec: group: topolvm.io diff --git a/docs/advanced-setup.md b/docs/advanced-setup.md index f7d82fe14..f96d57ca8 100644 --- a/docs/advanced-setup.md +++ b/docs/advanced-setup.md @@ -258,7 +258,7 @@ apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration metadata: name: config -kubernetesVersion: v1.34.3 +kubernetesVersion: v1.35.4 scheduler: extraVolumes: - name: "config" diff --git a/docs/maintenance.md b/docs/maintenance.md index 65c8fd739..183ccbdd6 100644 --- a/docs/maintenance.md +++ b/docs/maintenance.md @@ -29,23 +29,22 @@ Edit the following files. - `.github/workflows/e2e-k8s-workflow.yaml` - `test/e2e/README.md` -Next, we should update `go.mod` by the following commands. -Please note that Kubernetes v1 corresponds with v0 for the release tags. For example, v1.17.2 corresponds with the `v0.17.2` tag. +We should also update `go.mod`. According to [the Kubebuilder documentation](https://book.kubebuilder.io/versions_compatibility_supportability), we should use versions compatible with Kubebuilder, so refer to the samples in the latest Kubebuilder testdata directory (e.g., https://github.com/kubernetes-sigs/kubebuilder/blob/v4.1.1/testdata/project-v4/go.mod#L8-L11 and https://github.com/kubernetes-sigs/kubebuilder/blob/v4.1.1/testdata/project-v4/Makefile#L162) to see which versions should be used. + +First, update `k8s.io/*` libraries. Please note that Kubernetes v1 corresponds with v0 for the release tags. For example, v1.17.2 corresponds with the `v0.17.2` tag. ```console $ VERSION= $ go get k8s.io/api@v${VERSION} k8s.io/apimachinery@v${VERSION} k8s.io/client-go@v${VERSION} k8s.io/mount-utils@v${VERSION} ``` -Read the [controller-runtime's release note](https://github.com/kubernetes-sigs/controller-runtime/releases), and check which version is compatible with the Kubernetes versions. -Then, upgrade the controller-runtime's version by the following commands. +Next, update controller-runtime by the following command. Before updating it, please read the [`controller-runtime`'s release note](https://github.com/kubernetes-sigs/controller-runtime/releases). If there are breaking changes, we should decide how to manage these changes. ```console $ VERSION= $ go get sigs.k8s.io/controller-runtime@v${VERSION} ``` -Read the [`controller-tools`'s release note](https://github.com/kubernetes-sigs/controller-tools/releases), and update to the newest version that is compatible with all supported kubernetes versions. If there are breaking changes, we should decide how to manage these changes. -Then, upgrade the controller-tools's version by the following commands. +Then, update controller-tools. Before updating it, please read the [`controller-tools`'s release note](https://github.com/kubernetes-sigs/controller-tools/releases). If there are breaking changes, we should decide how to manage these changes. ```console $ VERSION= @@ -69,7 +68,7 @@ These are minimal changes for the Kubernetes upgrade, but if there are some brea #### Go -Choose the same version of Go [used by the latest Kubernetes](https://github.com/kubernetes/kubernetes/blob/master/go.mod) supported by TopoLVM. +Choose the version compatible with Kubebuilder (e.g., https://github.com/kubernetes-sigs/kubebuilder/blob/v4.1.1/testdata/project-v4/go.mod#L3). Edit the following files. - `go.mod` diff --git a/example/README.md b/example/README.md index 0c0e0e65a..638290985 100644 --- a/example/README.md +++ b/example/README.md @@ -7,7 +7,7 @@ and loopback block devices to run `lvmd`. You can try to use TopoLVM with a specific tag as follows. The demonstration is not guaranteed to work correctly with the main branch. ```console -$ git checkout topolvm-chart-v16.0.0 +$ git checkout topolvm-chart-v16.1.1 ``` To start the demonstration environment, run the following commands: diff --git a/internal/client/client.go b/internal/client/client.go index e34900cbc..a4fde8f34 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -456,3 +456,8 @@ func (c *wrappedSubResourceClient) Patch(ctx context.Context, obj client.Object, } return sc.Patch(ctx, obj, patch, opts...) } + +func (c *wrappedSubResourceClient) Apply(ctx context.Context, obj runtime.ApplyConfiguration, opts ...client.SubResourceApplyOption) error { + // We're not using SubResource Apply currently, so we can safely return an error here. + return fmt.Errorf("wrappedSubResourceClient.Apply is not implemented") +} diff --git a/internal/lvmd/command/lvm_command.go b/internal/lvmd/command/lvm_command.go index 3f5955d06..f6a74ffd1 100644 --- a/internal/lvmd/command/lvm_command.go +++ b/internal/lvmd/command/lvm_command.go @@ -73,7 +73,11 @@ func callLVMInto(ctx context.Context, into any, logVerbosity int, args ...string func callLVMStreamed(ctx context.Context, logVerbosity int, args ...string) (io.ReadCloser, error) { ctx = log.IntoContext(ctx, log.FromContext(ctx).WithCallDepth(1)) wholeCommand := slices.Concat(lvmCommandPrefix, args) - cmd := exec.Command(wholeCommand[0], wholeCommand[1:]...) + // Use CommandContext so kubelet timing out on an RPC (default 2 min + // csiTimeout) cancels the underlying vgs/lvs/... subprocess instead + // of leaving it running on the node. exec.Command ignores ctx and + // accumulates orphans under repeated timeout scenarios (#1163). + cmd := exec.CommandContext(ctx, wholeCommand[0], wholeCommand[1:]...) cmd.Env = os.Environ() cmd.Env = append(cmd.Env, "LC_ALL=C") return runCommand(ctx, logVerbosity, cmd) @@ -111,9 +115,12 @@ type commandReadCloser struct { stderr io.ReadCloser } -// Close closes stdout and stderr and waits for the command to exit. Close -// should not be called before all reads from stdout have completed. +// Close drains any unread stdout, reads stderr, and waits for the command to exit. func (p commandReadCloser) Close() error { + // Drain stdout before Wait() to prevent blocking when the caller stopped + // reading early and the child has more output than the pipe buffer. + _, _ = io.Copy(io.Discard, p.ReadCloser) + // Read the stderr output after the read has finished since we are sure by then the command must have run. stderr, err := io.ReadAll(p.stderr) if err != nil { diff --git a/internal/lvmd/command/lvm_command_test.go b/internal/lvmd/command/lvm_command_test.go index 79f81e386..dbfb1fe78 100644 --- a/internal/lvmd/command/lvm_command_test.go +++ b/internal/lvmd/command/lvm_command_test.go @@ -4,9 +4,11 @@ import ( "context" "fmt" "io" + "os/exec" "regexp" "strings" "testing" + "time" "github.com/go-logr/logr/funcr" "github.com/go-logr/logr/testr" @@ -152,3 +154,27 @@ func TestCallLVM(t *testing.T) { } }) } + +func TestCommandReadCloserClose(t *testing.T) { + t.Run("Close returns even when the caller stops reading early", func(t *testing.T) { + // Regression for #1161. + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + ctx = log.IntoContext(ctx, testr.New(t)) + cmd := exec.CommandContext(ctx, "dd", "if=/dev/zero", "bs=1024", "count=256", "status=none") + + rc, err := runCommand(ctx, verbosityLVMStateNoUpdate, cmd) + if err != nil { + t.Fatalf("runCommand: %v", err) + } + + buf := make([]byte, 4) + if _, err := io.ReadFull(rc, buf); err != nil { + t.Fatalf("read prefix: %v", err) + } + + if err := rc.Close(); err != nil { + t.Fatalf("close returned error: %v", err) + } + }) +} diff --git a/pkg/lvmd/proto/lvmd.pb.go b/pkg/lvmd/proto/lvmd.pb.go index 18d7722e3..ab8f6fa42 100644 --- a/pkg/lvmd/proto/lvmd.pb.go +++ b/pkg/lvmd/proto/lvmd.pb.go @@ -8,7 +8,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.10 -// protoc v6.33.2 +// protoc v7.34.1 // source: pkg/lvmd/proto/lvmd.proto package proto diff --git a/pkg/lvmd/proto/lvmd_grpc.pb.go b/pkg/lvmd/proto/lvmd_grpc.pb.go index e02176d6d..21d174ece 100644 --- a/pkg/lvmd/proto/lvmd_grpc.pb.go +++ b/pkg/lvmd/proto/lvmd_grpc.pb.go @@ -8,7 +8,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v6.33.2 +// - protoc v7.34.1 // source: pkg/lvmd/proto/lvmd.proto package proto diff --git a/test/e2e/README.md b/test/e2e/README.md index e44f958ee..a2cb71e52 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -91,8 +91,8 @@ You can use the following script to run the tests using Minikube on [Multipass]( set -euxo pipefail -GOVERSION=1.24.3 # Choose a supported version -KUBERNETES_VERSION=1.34.3 # Choose a supported version +GOVERSION=1.25.7 # Choose a supported version +KUBERNETES_VERSION=1.35.4 # Choose a supported version multipass delete -p testvm || true multipass launch lts --name testvm --memory 8G --disk 20G --cpus 4 diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 2bb21d425..4d046031f 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -615,7 +615,7 @@ func testE2E() { var maxCapNodes []string Eventually(func() error { var maxCapacity int - maxCapNodes = []string{} + maxCapNodes = make([]string, 0, 2) var nodes corev1.NodeList err := getObjects(&nodes, "nodes") if err != nil { @@ -637,7 +637,8 @@ func testE2E() { switch { case capacity > maxCapacity: maxCapacity = capacity - maxCapNodes = []string{node.GetName()} + maxCapNodes = maxCapNodes[:0] + maxCapNodes = append(maxCapNodes, node.GetName()) case capacity == maxCapacity: maxCapNodes = append(maxCapNodes, node.GetName()) } diff --git a/test/e2e/read_write_once_pod_test.go b/test/e2e/read_write_once_pod_test.go index 9adde9efc..b6ae923bb 100644 --- a/test/e2e/read_write_once_pod_test.go +++ b/test/e2e/read_write_once_pod_test.go @@ -87,8 +87,8 @@ func testReadWriteOncePod() { for _, c := range pod.Status.Conditions { //nolint:lll - // https://github.com/kubernetes/kubernetes/blob/v1.22.0/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go#L53-L54 - // https://github.com/kubernetes/kubernetes/blob/v1.34.0/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go#L58-L59 + // https://github.com/kubernetes/kubernetes/blob/v1.33.7/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go#L57-L58 + // https://github.com/kubernetes/kubernetes/blob/v1.35.4/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go#L59-L60 //nolint:lll if c.Type == corev1.PodScheduled && diff --git a/versions.mk b/versions.mk index 26d94b11d..c2df63603 100644 --- a/versions.mk +++ b/versions.mk @@ -1,37 +1,37 @@ # https://github.com/docker/buildx/releases -BUILDX_VERSION := 0.30.1 +BUILDX_VERSION := 0.33.0 # If you update the version, you also need to update getting-started.md. # https://github.com/cert-manager/cert-manager/releases CERT_MANAGER_VERSION := v1.17.4 # https://github.com/helm/chart-testing/releases CHART_TESTING_VERSION := 3.14.0 # https://github.com/containernetworking/plugins/releases -CNI_PLUGINS_VERSION := v1.9.0 +CNI_PLUGINS_VERSION := v1.9.1 # https://github.com/GoogleContainerTools/container-structure-test/releases -CONTAINER_STRUCTURE_TEST_VERSION := 1.22.0 +CONTAINER_STRUCTURE_TEST_VERSION := 1.22.1 # https://github.com/Mirantis/cri-dockerd/releases -CRI_DOCKERD_VERSION := v0.3.21 +CRI_DOCKERD_VERSION := v0.4.2 # https://github.com/kubernetes-sigs/cri-tools/releases CRICTL_VERSION := v1.35.0 # https://github.com/golangci/golangci-lint/releases -GOLANGCI_LINT_VERSION := v2.7.2 +GOLANGCI_LINT_VERSION := v2.11.4 # https://github.com/norwoodj/helm-docs/releases HELM_DOCS_VERSION := 1.14.2 # https://github.com/helm/helm/releases -HELM_VERSION := 3.19.4 +HELM_VERSION := 3.20.2 # kind node image version is related to kind version. # if you change kind version, also change kind node image version. # https://github.com/kubernetes-sigs/kind/releases KIND_VERSION := v0.31.0 # It is set by CI using the environment variable, use conditional assignment. -KUBERNETES_VERSION ?= 1.34.3 +KUBERNETES_VERSION ?= 1.35.4 KUBERNETES_MINOR = $(shell echo $(KUBERNETES_VERSION) | cut -d '.' -f2) # https://github.com/kubernetes/minikube/releases -MINIKUBE_VERSION := v1.37.0 +MINIKUBE_VERSION := v1.38.1 # https://github.com/protocolbuffers/protobuf/releases -PROTOC_VERSION := 33.2 +PROTOC_VERSION := 34.1 # https://github.com/mikefarah/yq/releases -YQ_VERSION := 4.50.1 +YQ_VERSION := 4.53.2 # Tools versions which are defined in go.mod SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) @@ -46,22 +46,24 @@ ENVTEST_KUBERNETES_VERSION := $(shell echo $(KUBERNETES_VERSION) | cut -d "." -f # CSI sidecar versions # https://github.com/kubernetes-csi/external-provisioner/releases -EXTERNAL_PROVISIONER_VERSION := 5.3.0 +EXTERNAL_PROVISIONER_VERSION := 6.2.0 # https://github.com/kubernetes-csi/external-resizer/releases -EXTERNAL_RESIZER_VERSION := 2.0.0 +EXTERNAL_RESIZER_VERSION := 2.1.0 # https://github.com/kubernetes-csi/external-snapshotter/releases -EXTERNAL_SNAPSHOTTER_VERSION := 8.4.0 +EXTERNAL_SNAPSHOTTER_VERSION := 8.5.0 # https://github.com/kubernetes-csi/livenessprobe/releases -LIVENESSPROBE_VERSION := 2.17.0 +LIVENESSPROBE_VERSION := 2.18.0 # https://github.com/kubernetes-csi/node-driver-registrar/releases -NODE_DRIVER_REGISTRAR_VERSION := 2.15.0 +NODE_DRIVER_REGISTRAR_VERSION := 2.16.0 # The container version of kind must be with the digest. # ref. https://github.com/kubernetes-sigs/kind/releases -ifeq ($(KUBERNETES_VERSION), 1.34.3) +# NOTE: If kind does not have a prebuilt image for the exact patch version, +# we use the image from the latest available patch version for the same minor version. +ifeq ($(KUBERNETES_VERSION), 1.35.4) + KIND_NODE_IMAGE=kindest/node:v1.35.0@sha256:452d707d4862f52530247495d180205e029056831160e22870e37e3f6c1ac31f +else ifeq ($(KUBERNETES_VERSION), 1.34.3) KIND_NODE_IMAGE=kindest/node:v1.34.3@sha256:08497ee19eace7b4b5348db5c6a1591d7752b164530a36f855cb0f2bdcbadd48 else ifeq ($(KUBERNETES_VERSION), 1.33.7) KIND_NODE_IMAGE=kindest/node:v1.33.7@sha256:d26ef333bdb2cbe9862a0f7c3803ecc7b4303d8cea8e814b481b09949d353040 -else ifeq ($(KUBERNETES_VERSION), 1.32.11) - KIND_NODE_IMAGE=kindest/node:v1.32.11@sha256:5fc52d52a7b9574015299724bd68f183702956aa4a2116ae75a63cb574b35af8 endif