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
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,20 @@ jobs:
cache: true
- name: Install FUSE
run: sudo apt-get update && sudo apt-get install -y fuse3
- name: Install krew
run: |
cd "$(mktemp -d)"
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-linux_amd64.tar.gz"
tar zxf krew-linux_amd64.tar.gz
./krew-linux_amd64 install krew
echo "${HOME}/.krew/bin" >> "$GITHUB_PATH"
- uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0, kind v0.31.0, kubectl v1.35.0
with:
cluster_name: vifal-test
node_image: kindest/node:v1.35.0@sha256:452d707d4862f52530247495d180205e029056831160e22870e37e3f6c1ac31f
- run: make e2e-test-shell
env:
VIFAL_E2E_KREW: "1"
# With race detector and no attr caching.
- run: FUSE_TIMEOUT=5 make e2e-test-shell-nocache
env:
Expand Down
68 changes: 65 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,58 @@ on:
permissions: {}

jobs:
release:
create-release:
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Create draft release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "${GITHUB_REF_NAME}" --draft --generate-notes

build:
runs-on: ubuntu-24.04
needs: create-release
permissions:
contents: write
strategy:
matrix:
include:
- goos: linux
goarch: amd64
- goos: linux
goarch: arm64
- goos: darwin
goarch: amd64
- goos: darwin
goarch: arm64
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod

- name: Build and package
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
run: make release-archive VERSION="${GITHUB_REF_NAME}" GOOS="${GOOS}" GOARCH="${GOARCH}"

- name: Upload asset
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "${GITHUB_REF_NAME}" "kubectl-vifal_${GITHUB_REF_NAME}_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz"

publish:
runs-on: ubuntu-24.04
needs: build
permissions:
contents: write
steps:
Expand All @@ -24,7 +74,19 @@ jobs:
GOPROXY: proxy.golang.org
run: go list -m "github.com/machine424/vifal@${GITHUB_REF_NAME}"

- name: Create GitHub release
- name: Publish release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "${GITHUB_REF_NAME}"
run: gh release edit "${GITHUB_REF_NAME}" --draft=false

update-krew-index:
runs-on: ubuntu-24.04
needs: publish
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Update krew-index
uses: rajatjindal/krew-release-bot@c970b8a8f6dbc2f2285a26e3ae160903b87002c3 # v0.0.51
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# Build output
vifal
kubectl-vifal
kubectl-vifal_*.tar.gz

# macOS
.DS_Store
Expand Down
48 changes: 48 additions & 0 deletions .krew.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: vifal
spec:
version: {{ .TagName }}
homepage: https://github.com/machine424/vifal
platforms:
- selector:
matchLabels:
os: linux
arch: amd64
{{addURIAndSha "https://github.com/machine424/vifal/releases/download/{{ .TagName }}/kubectl-vifal_{{ .TagName }}_linux_amd64.tar.gz" .TagName }}
bin: kubectl-vifal
- selector:
matchLabels:
os: linux
arch: arm64
{{addURIAndSha "https://github.com/machine424/vifal/releases/download/{{ .TagName }}/kubectl-vifal_{{ .TagName }}_linux_arm64.tar.gz" .TagName }}
bin: kubectl-vifal
- selector:
matchLabels:
os: darwin
arch: amd64
{{addURIAndSha "https://github.com/machine424/vifal/releases/download/{{ .TagName }}/kubectl-vifal_{{ .TagName }}_darwin_amd64.tar.gz" .TagName }}
bin: kubectl-vifal
- selector:
matchLabels:
os: darwin
arch: arm64
{{addURIAndSha "https://github.com/machine424/vifal/releases/download/{{ .TagName }}/kubectl-vifal_{{ .TagName }}_darwin_arm64.tar.gz" .TagName }}
bin: kubectl-vifal
shortDescription: exposing and unifying Kubernetes container filesystems locally
description: |
FUSE mount that exposes and unifies Kubernetes container filesystems locally.
Browse namespaces, pods, and containers as directories, read files, and diff
configs across pods using standard shell tools.
caveats: |
Requires FUSE:
- Linux: install fuse3
- macOS: install macFUSE (https://github.com/macfuse/macfuse)

Containers must have sh, stat, find, and dd available.

Usage:
kubectl vifal /mnt/my-cluster
ls /mnt/my-cluster/<namespace>/<pod>/<container>/
kubectl vifal unmount /mnt/my-cluster
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
BINARY = vifal
BINARY ?= vifal
GOLANGCI_LINT_VERSION = v2.12.1
GO_LICENSES_VERSION = v2.0.1
GO_BUILD_FLAGS ?=
GO_LDFLAGS ?= -s -w
TIMEOUT_CMD = timeout --foreground
.PHONY: build build-debug build-race clean test unit-test e2e-test e2e-test-go e2e-test-shell e2e-test-shell-debug e2e-test-shell-nocache lint shellcheck licenses-check
.PHONY: build build-debug build-race release-archive clean test unit-test e2e-test e2e-test-go e2e-test-shell e2e-test-shell-debug e2e-test-shell-nocache lint shellcheck licenses-check

build:
go build $(GO_BUILD_FLAGS) -ldflags="$(GO_LDFLAGS)" -o $(BINARY) .
Expand All @@ -15,6 +15,10 @@ build-debug:
build-race:
$(MAKE) --no-print-directory build GO_BUILD_FLAGS=-race GO_LDFLAGS=

release-archive:
$(MAKE) --no-print-directory build BINARY=kubectl-vifal
tar czf "kubectl-vifal_$(VERSION)_$(GOOS)_$(GOARCH).tar.gz" kubectl-vifal LICENSE LICENSES/

test: unit-test e2e-test

unit-test:
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ Works on Linux and macOS.
- Linux: install `fuse3`.
- macOS: install [macFUSE](https://github.com/macfuse/macfuse/wiki/Getting-Started). The mount appears as a network volume, so your terminal may need [access to network volumes](https://github.com/macfuse/macfuse/issues/690#issuecomment-1527424231).

Via [Krew](https://krew.sigs.k8s.io/) (kubectl plugin manager):

```bash
$ kubectl krew install vifal
```

Via `go install`:

```bash
$ go install github.com/machine424/vifal@latest
```
Expand Down
18 changes: 18 additions & 0 deletions e2e/krew-test-manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Static manifest for testing krew install locally (with --archive).
# The test script replaces SHA256SUM with the real checksum at runtime.
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: vifal
spec:
version: v0.0.0-ci
platforms:
- selector:
matchLabels:
os: linux
arch: amd64
uri: https://example.com/placeholder.tar.gz
sha256: SHA256SUM
bin: kubectl-vifal
shortDescription: test
description: test
56 changes: 56 additions & 0 deletions e2e/tests/krew.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Test vifal as a kubectl plugin installed via krew: install, mount, read, unmount, uninstall.
# Skipped unless VIFAL_E2E_KREW=1 (set in CI after installing krew).

if [ "${VIFAL_E2E_KREW:-}" != "1" ]; then
log_step "SKIP: VIFAL_E2E_KREW not set"
return 0
fi

NAMESPACE="vifal-krew"
TEST_DIR=$(mktemp -d /tmp/vifal-krew-XXXXXX)
MOUNT="$TEST_DIR/mount"
LOGS="$TEST_DIR"

setup() {
kubectl delete namespace "$NAMESPACE" --ignore-not-found
mkdir -p "$MOUNT"
kubectl create namespace "$NAMESPACE"
kubectl run nginx --image="$IMAGE" -n "$NAMESPACE" --overrides="$FAST_TERM" --command -- sleep infinity
kubectl wait --for=condition=Ready pod/nginx -n "$NAMESPACE" --timeout="${KUBECTL_TIMEOUT}s"
}

teardown() {
dump_vifal_logs "$?"
kubectl vifal unmount "$MOUNT" 2>/dev/null || true
kubectl krew uninstall vifal 2>/dev/null || true
rm -rf "$TEST_DIR"
kubectl delete namespace "$NAMESPACE" --ignore-not-found --wait=false
}

trap teardown EXIT
setup

log_step "build and install via krew"
MANIFEST="$TEST_DIR/manifest.yaml"
ARCHIVE="kubectl-vifal_v0.0.0-ci_linux_amd64.tar.gz"
make -s release-archive VERSION=v0.0.0-ci GOOS=linux GOARCH=amd64
# krew validates sha256 even with --archive, patch the placeholder in the manifest.
sed "s/SHA256SUM/$(sha256sum "$ARCHIVE" | awk '{print $1}')/" "$DIR/krew-test-manifest.yaml" > "$MANIFEST"
kubectl krew install --manifest="$MANIFEST" --archive="$ARCHIVE"
rm -f "$ARCHIVE" kubectl-vifal

log_step "mount"
kubectl vifal --fsname "$VIFAL_SHELL_TEST" --attr-ttl "$CACHE_TTL" "$MOUNT" 2>"$LOGS/vifal.log" &
VIFAL_PID=$!
wait_for_fuse_sync "$MOUNT/$NAMESPACE/nginx/nginx"

log_step "read file"
diff <(fuse cat "$MOUNT/$NAMESPACE/nginx/nginx/etc/hostname") <(kubectl exec nginx -n "$NAMESPACE" -c nginx -- cat /etc/hostname)

log_step "unmount"
kubectl vifal unmount "$MOUNT"
wait_process_dead "$VIFAL_PID"
check_clean_unmount "$MOUNT"

log_step "krew uninstall"
kubectl krew uninstall vifal
Loading