Cloud Storage FUSE CSI Driver Development Guide
August 27, 2026 ยท View on GitHub
Prerequisites
The following software are required for local development.
-
Run the following command to install GCC Compiler on Linux:
sudo apt-get update && sudo apt-get install build-essential -y
Create a registry to host a custom driver image. This is needed if you want to build and install a custom GCSFuse CSI Driver. Here is how you would create an artifact registry:
export REGION='us-central1'
export PROJECT_ID=$(gcloud config get project)
gcloud artifacts repositories create csi-dev \
--repository-format=docker \
--location=$REGION --project=$PROJECT_ID \
--description="Docker repository"
export REGISTRY="$REGION-docker.pkg.dev/$PROJECT_ID/csi-dev"
Build
You have two options for building a custom image for the Cloud Storage FUSE CSI Driver. You can use Cloud build, or Makefile commands. Please note that building the image will take several minutes. If you don't want to build a custom image, you can also deploy the driver from a publicly hosted image.
Prerequisites
Cloud Build
Run the following command to build and push the images using cloud build. If you created an artifact registry according to the Prerequisites, your REGISTRY would be as shown below. The _REGISTRY substitution is currently required for Cloud Build. If you would like to override _STAGINGVERSION, which is the version tag for the image, you can append _STAGINGVERSION=<staging-version> to the --substitutions. The default is v999.999.999. Please see the cloudbuild-build-image.yaml file for information on additional substitutions.
Cloud Build on Google Internal projects
For running cloud build from a Google Internal project, you can use the following command. This will use the gcsfuse version present in cmd/sidecar_mounter/gcsfuse_binary as the gcsfuse binary. You can change this to a different version, or use _BUILD_GCSFUSE_FROM_SOURCE=true to build gcsfuse from HEAD. Setting GCSFUSE_BINARY_GCS_PATH to the gke-release-staging bucket in cmd/sidecar_mounter/gcsfuse_binary is only allowed for Google Internal projects because artifacts in gke-release-staging are not publicly accessible.
Note that this currently isn't working because gcloud isn't installed the prepare-gcsfuse-binary step image, so for now, use the make install command if you want to run at the GCSFuse version in _GCSFUSE_BINARY_GCS_PATH on Google internal project.
export PROJECT_ID=$(gcloud config get project)
export REGION='us-central1'
export REGISTRY="$REGION-docker.pkg.dev/$PROJECT_ID/csi-dev"
export GCSFUSE_BINARY_GCS_PATH=$(cat cmd/sidecar_mounter/gcsfuse_binary)
export STAGINGVERSION=v999.999.999
gcloud builds submit . --config=cloudbuild-build-image.yaml --substitutions=_REGISTRY=$REGISTRY,_GCSFUSE_BINARY_GCS_PATH=$GCSFUSE_BINARY_GCS_PATH,_STAGINGVERSION=$STAGINGVERSION
Cloud Build on NON Google Internal projects
If you are running this from a non-google internal project, you must set _BUILD_GCSFUSE_FROM_SOURCE=true, because without this, gcsfuse is loaded from the binary in gke-release-staging, which is not publicly accessible. By default, _BUILD_GCSFUSE_FROM_SOURCE=true will build GCSFuse from the master branch. If you would like to run from a particular GCSFuse release tag instead of master, run the following commands to find the latest GCSFuse release supported by our driver. Running from a GCSFuse release rather than master is recommended as GCSFuse master branch isn't always stable like releases, which have gone through extensive qualification testing.
export LATEST_TAG=$(curl -s "https://api.github.com/repos/GoogleCloudPlatform/gcs-fuse-csi-driver/releases/latest" | jq -r .tag_name)
export GCSFUSE_TAG=$(curl -sL "https://raw.githubusercontent.com/GoogleCloudPlatform/gcs-fuse-csi-driver/$LATEST_TAG/cmd/sidecar_mounter/gcsfuse_binary" | cut -d'/' -f5 | cut -d'-' -f1)
echo "latest GCSFuse CSI driver release is $LATEST_TAG, which uses GCSFuse version $GCSFUSE_TAG"
After you have found the latest GCSFUSE_VERSION, pass that to the cloudbuild script with the _GCSFUSE_TAG substitution.
export PROJECT_ID=$(gcloud config get project)
export REGION='us-central1'
export REGISTRY="$REGION-docker.pkg.dev/$PROJECT_ID/csi-dev"
export STAGINGVERSION=v999.999.999
gcloud builds submit . --config=cloudbuild-build-image.yaml --substitutions=_REGISTRY=$REGISTRY,_BUILD_GCSFUSE_FROM_SOURCE=true,_GCSFUSE_TAG=$GCSFUSE_TAG,_STAGINGVERSION=$STAGINGVERSION
Makefile Commands
Run the following command to build and push the images using the Makefile. For non-Google Internal projects, you must set BUILD_GCSFUSE_FROM_SOURCE=true. By default, BUILD_GCSFUSE_FROM_SOURCE will build GCSFuse from head of the master branch, which isn't always stable. Instead, we recommend setting GCSFUSE_TAG to build from a qualified GCSFuse tag.
export LATEST_TAG=$(curl -s "https://api.github.com/repos/GoogleCloudPlatform/gcs-fuse-csi-driver/releases/latest" | jq -r .tag_name)
export GCSFUSE_TAG=$(curl -sL "https://raw.githubusercontent.com/GoogleCloudPlatform/gcs-fuse-csi-driver/$LATEST_TAG/cmd/sidecar_mounter/gcsfuse_binary" | cut -d'/' -f5 | cut -d'-' -f1)
echo "latest GCSFuse CSI driver release is $LATEST_TAG, which uses GCSFuse version $GCSFUSE_TAG"
# REGISTRY=<your-container-registry>: Required. Define your container registry. Make sure you have logged in your registry so that you have image pull/push permissions.
# STAGINGVERSION=<staging-version>: Optional. Define a build version. If not defined, a staging version will be generated based on the commit hash.
# BUILD_GCSFUSE_FROM_SOURCE=<true|false>: Optional, default: false. Indicate if you want to build the gcsfuse binary from source. This is required for building images from non-google internal projects OR if you want to test any CSI change depend on an unreleased GCSFuse enhancement. If BUILD_GCSFUSE_FROM_SOURCE is true, by default it builds GCSFuse from head of the master branch. If you want to build GCSFuse from a particular tag, then set GCSFUSE_TAG as explained in cloudbuild sections above. This flag is also automatically set by GCSFUSE_PR_NUMBER.
# GCSFUSE_TAG=<gcsfuse-tag>: Optional. The GCSFuse tag you would like to build GCSFuse from. This is only used if BUILD_GCSFUSE_FROM_SOURCE is set to true.
make build-image-and-push-multi-arch REGISTRY=$REGISTRY STAGINGVERSION=v999.999.999
Building GCSFuse from a specific GCSFuse PR (Optional)
To test the CSI driver against a specific GCSFuse PR, pass GCSFUSE_PR_NUMBER. This automatically implies BUILD_GCSFUSE_FROM_SOURCE=true and resolves the PR's fork repo URL and branch name from the GitHub API. Works for both main-repo and fork PRs.
make build-image-and-push-multi-arch \
REGISTRY=$REGISTRY STAGINGVERSION=v999.999.999 \
GCSFUSE_PR_NUMBER=4651
Note:
BUILD_GCSFUSE_FROM_SOURCEandGCSFUSE_PR_NUMBERserve related but distinct purposes:
BUILD_GCSFUSE_FROM_SOURCE=truealone builds GCSFuse frommaster(or the branch/tag specified byGCSFUSE_TAG).GCSFUSE_PR_NUMBER=<N>impliesBUILD_GCSFUSE_FROM_SOURCE=trueand also fetches the test configuration from that PR.
Running E2E Tests from a Customized GCSFuse Release Branch
When BUILD_GCSFUSE_FROM_SOURCE=true is set along with GCSFUSE_TAG (e.g., GCSFUSE_TAG=v3.7.0), the testing framework performs two key actions:
- Driver Image Build: It builds the driver image using the GCSFuse binary from the specified tag.
- E2E Test Execution: During E2E testing, the framework dynamically fetches the
gcsfuseversion from the running pod and automatically checks out the corresponding release branch (e.g.,v3.7.0_release) from the GCSFuse repository. This ensures that the integration tests executed exactly match the GCSFuse version running inside the driver.
To run the E2E tests using a customized release branch, execute:
make e2e-test E2E_TEST_USE_GKE_MANAGED_DRIVER=false E2E_TEST_BUILD_DRIVER=true \
BUILD_GCSFUSE_FROM_SOURCE=true GCSFUSE_TAG=v3.7.0 \
STAGINGVERSION=v999.999.999 REGISTRY=$REGISTRY
Manual installation
Refer to Cloud Storage FUSE CSI Driver Manual Installation documentation.
Test
Refer to Test documentation.
Update go modules
Follow the following steps to update go modules:
Root Module (go.mod)
- Open the go.mod file in Visual Studio Code.
- Click "Check for upgrades" above the first
requireblock. - Hover over the module with available upgrade. Click "Quick Fix" to apply the upgrade.
- If you upgraded any
k8s.iomodules, make sure the version is also updated in thereplaceblock. You need to do this step because lack of semantic versioning preventsgo modfrom finding newer releases. - Run
go mod tidyto ensure that the listed dependencies are really still needed. - Run
go mod vendorto update vendor directory. - Resolve any issues that may be introduced by the new modules.
Test Module (test/go.mod)
The test/ directory maintains its own Go module. Tests run with -mod=readonly:
- Add or update dependencies in
test/go.mod. - Tidy the test module dependencies:
cd test && go mod tidy - Commit the updated
test/go.modandtest/go.sum.
Troubleshooting
Refer to Troubleshooting documentation.