Full Code of fstab/cifs for AI

master 3b640936ef51 cached
3 files
11.4 KB
3.1k tokens
1 requests
Download .txt
Repository: fstab/cifs
Branch: master
Commit: 3b640936ef51
Files: 3
Total size: 11.4 KB

Directory structure:
gitextract_r1vlbl9p/

├── LICENSE
├── README.md
└── cifs

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
Copyright 2019 Fabian Stäber (https://github.com/fstab/cifs)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
CIFS Flexvolume Plugin for Kubernetes
=====================================

Driver for [CIFS][1] (SMB, Samba, Windows Share) network filesystems as [Kubernetes volumes][2].

Background
----------

Docker containers running in Kubernetes have an ephemeral file system: Once a container is terminated, all files are gone. In order to store persistent data in Kubernetes, you need to mount a [Persistent Volume][3] into your container. Kubernetes has built-in support for network filesystems found in the most common cloud providers, like [Amazon's EBS][4], [Microsoft's Azure disk][5], etc. However, some cloud hosting services, like the [Hetzner cloud][6], provide network storage using the CIFS (SMB, Samba, Windows Share) protocol, which is not natively supported in Kubernetes.

Fortunately, Kubernetes provides [Flexvolume][7], which is a plugin mechanism enabling users to write their own drivers. There are a few flexvolume drivers for CIFS out there, but for different reasons none of them seemed to work for me. So I wrote my own, which can be found on [github.com/fstab/cifs][8].

Installing
----------

The flexvolume plugin is a single shell script named [cifs][8]. This shell script must be available on the Kubernetes master and on each of the Kubernetes nodes. By default, Kubernetes searches for third party volume plugins in `/usr/libexec/kubernetes/kubelet-plugins/volume/exec/`. The plugin directory can be configured with the kubelet's `--volume-plugin-dir` parameter, run `ps aux | grep kubelet` to learn the location of the plugin directory on your system (see [#1][9]). The `cifs` script must be located in a subdirectory named `fstab~cifs/`. The directory name `fstab~cifs/` will be [mapped][10] to the Flexvolume driver name `fstab/cifs`.

On the Kubernetes master and on each Kubernetes node run the following commands:

```bash
VOLUME_PLUGIN_DIR="/usr/libexec/kubernetes/kubelet-plugins/volume/exec"
mkdir -p "$VOLUME_PLUGIN_DIR/fstab~cifs"
cd "$VOLUME_PLUGIN_DIR/fstab~cifs"
curl -L -O https://raw.githubusercontent.com/fstab/cifs/master/cifs
chmod 755 cifs
```

The `cifs` script requires a few executables to be available on each host system:

* `mount.cifs`, on Ubuntu this is in the [cifs-utils][11] package.
* `jq`, on Ubuntu this is in the [jq][12] package.
* `mountpoint`, on Ubuntu this is in the [util-linux][13] package.
* `base64`, on Ubuntu this is in the [coreutils][14] package.

To check if the installation was successful, run the following command:

```bash
VOLUME_PLUGIN_DIR="/usr/libexec/kubernetes/kubelet-plugins/volume/exec"
$VOLUME_PLUGIN_DIR/fstab~cifs/cifs init
```

It should output a JSON string containing `"status": "Success"`. This command is also run by Kubernetes itself when the cifs plugin is detected on the file system.

Running
-------

The plugin takes the CIFS username and password from a [Kubernetes Secret][15]. To create the secret, you first have to convert your username and password to base64 encoding:

```bash
echo -n username | base64
echo -n password | base64
```

Then, create a file `secret.yml` and use the ouput of the above commands as username and password:

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: cifs-secret
  namespace: default
type: fstab/cifs
data:
  username: 'ZXhhbXBsZQ=='
  password: 'bXktc2VjcmV0LXBhc3N3b3Jk'
```

Apply the secret:

```bash
kubectl apply -f secret.yml
```

You can check if the secret was installed successfully using `kubectl describe secret cifs-secret`.

Next, create a file `pod.yml` with a test pod (replace `//server/share` with the network path of your CIFS share):

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: busybox
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: test
      mountPath: /data
  volumes:
  - name: test
    flexVolume:
      driver: "fstab/cifs"
      fsType: "cifs"
      secretRef:
        name: "cifs-secret"
      options:
        networkPath: "//server/share"
        mountOptions: "dir_mode=0755,file_mode=0644,noperm"
```

Start the pod:

```yaml
kubectl apply -f pod.yml
```

You can verify that the volume was mounted successfully using `kubectl describe pod busybox`.

Testing
-------

If everything is fine, start a shell inside the container to see if it worked:

```bash
kubectl exec -ti busybox /bin/sh
```

Inside the container, you should see the CIFS share mounted to `/data`.

[1]: https://en.wikipedia.org/wiki/Server_Message_Block
[2]: https://kubernetes.io/docs/concepts/storage/volumes/
[3]: https://kubernetes.io/docs/concepts/storage/volumes/
[4]: https://aws.amazon.com/ebs
[5]: https://azure.microsoft.com/en-us/services/storage/unmanaged-disks/
[6]: https://hetzner.cloud
[7]: https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md
[8]: https://github.com/fstab/cifs
[9]: https://github.com/fstab/cifs/issues/1
[10]: https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md#prerequisites
[11]: https://packages.ubuntu.com/bionic/cifs-utils
[12]: https://packages.ubuntu.com/bionic/jq
[13]: https://packages.ubuntu.com/bionic/util-linux
[14]: https://packages.ubuntu.com/bionic/coreutils
[15]: https://kubernetes.io/docs/concepts/configuration/secret/


================================================
FILE: cifs
================================================
#!/bin/bash

set -u

# ====================================================================
# Example configuration:
# ====================================================================
# --------------------------------------------------------------------
# secret.yml:
# --------------------------------------------------------------------
# apiVersion: v1
# kind: Secret
# metadata:
#   name: cifs-secret
#   namespace: default
# type: fstab/cifs
# data:
#   username: 'ZXhhbXBsZQo='
#   password: 'c2VjcmV0Cg=='
#
# --------------------------------------------------------------------
# pod.yml:
# --------------------------------------------------------------------
# apiVersion: v1
# kind: Pod
# metadata:
#   name: busybox
#   namespace: default
# spec:
#   containers:
#   - name: busybox
#     image: busybox
#     command:
#       - sleep
#       - "3600"
#     imagePullPolicy: IfNotPresent
#     volumeMounts:
#     - name: test
#       mountPath: /data
#   volumes:
#   - name: test
#     flexVolume:
#       driver: "fstab/cifs"
#       fsType: "cifs"
#       secretRef:
#         name: "cifs-secret"
#       options:
#         networkPath: "//example-server/backup"
#         mountOptions: "dir_mode=0755,file_mode=0644,noperm"
# --------------------------------------------------------------------

# Uncomment the following lines to see how this plugin is called:
# echo >> /tmp/cifs.log
# date >> /tmp/cifs.log
# echo "$@" >> /tmp/cifs.log

init() {
	assertBinaryInstalled mount.cifs cifs-utils
	assertBinaryInstalled jq jq
	assertBinaryInstalled mountpoint util-linux
	assertBinaryInstalled base64 coreutils
	echo '{ "status": "Success", "message": "The fstab/cifs flexvolume plugin was initialized successfully", "capabilities": { "attach": false } }'
	exit 0
}

assertBinaryInstalled() {
	binary="$1"
	package="$2"
	if ! which "$binary" > /dev/null ; then
		errorExit "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package."
	fi
}

errorExit() {
	if [[ $# -ne 1 ]] ; then
		echo '{ "status": "Failure", "message": "Unknown error in the fstab/cifs flexvolume plugin." }'
	else
		jq -Mcn --arg message "$1" '{ "status": "Failure", "message": $message }'
	fi
	exit 1
}

doMount() {
	if [[ -z ${1:-} || -z ${2:-} ]] ; then
		errorExit "cifs mount: syntax error. usage: cifs mount <mount dir> <json options>"
	fi
	mountPoint="$1"
	shift
	json=$(printf '%s ' "${@}")
	if ! jq -e . > /dev/null 2>&1 <<< "$json" ; then
		errorExit "cifs mount: syntax error. invalid json: '$json'"
	fi
	networkPath="$(jq --raw-output -e '.networkPath' <<< "$json" 2>/dev/null)"
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: option networkPath missing in flexvolume configuration."
	fi
	mountOptions="$(jq --raw-output -e '.mountOptions' <<< "$json" 2>/dev/null)"
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: option mountOptions missing in flexvolume configuration."
	fi
	cifsUsernameBase64="$(jq --raw-output -e '.["kubernetes.io/secret/username"]' <<< "$json" 2>/dev/null)"
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: username not found. the flexVolume definition must contain a secretRef to a secret with username and password."
	fi
	cifsPasswordBase64="$(jq --raw-output -e '.["kubernetes.io/secret/password"]' <<< "$json" 2>/dev/null)"
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: password not found. the flexVolume definition must contain a secretRef to a secret with username and password."
	fi
	cifsUsername="$(base64 --decode <<< "$cifsUsernameBase64" 2>/dev/null)"
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: username secret is not base64 encoded."
	fi
	cifsPassword="$(base64 --decode <<< "$cifsPasswordBase64" 2>/dev/null)"
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: password secret is not base64 encoded."
	fi
	if ! mkdir -p "$mountPoint" > /dev/null 2>&1 ; then
		errorExit "cifs mount: failed to create mount directory: '$mountPoint'"
	fi
	if [[ $(mountpoint "$mountPoint") = *"is a mountpoint"* ]] ; then
		errorExit "cifs mount: there is already a filesystem mounted under the mount directory: '$mountPoint'"
	fi
	if [[ ! -z $(ls -A "$mountPoint" 2>/dev/null) ]] ; then
		errorExit "cifs mount: mount directory is not an empty directory: '$mountPoint'"
	fi

	export PASSWD="$cifsPassword"
	result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions" 2>&1)
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs mount: failed to mount the network path: $result"
	fi
	echo '{ "status": "Success" }'
	exit 0
}

doUnmount() {
	if [[ -z ${1:-} ]] ; then
		errorExit "cifs unmount: syntax error. usage: cifs unmount <mount dir>"
	fi
	mountPoint="$1"
	if [[ $(mountpoint "$mountPoint") != *"is a mountpoint"* ]] ; then
		errorExit "cifs unmount: no filesystem mounted under directory: '$mountPoint'"
	fi
	result=$(umount "$mountPoint" 2>&1)
	if [[ $? -ne 0 ]] ; then
		errorExit "cifs unmount: failed to unmount the network path: $result"
	fi
	echo '{ "status": "Success" }'
	exit 0
}

not_supported() {
	echo '{ "status": "Not supported" }'
	exit 1
}

command=${1:-}
if [[ -n $command ]]; then
	shift
fi

case "$command" in
	init)
		init "$@"
		;;
	mount)
		doMount "$@"
		;;
	unmount)
		doUnmount "$@"
		;;
	*)
		not_supported "$@"
		;;
esac
Download .txt
gitextract_r1vlbl9p/

├── LICENSE
├── README.md
└── cifs
Condensed preview — 3 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (12K chars).
[
  {
    "path": "LICENSE",
    "chars": 1085,
    "preview": "Copyright 2019 Fabian Stäber (https://github.com/fstab/cifs)\n\nPermission is hereby granted, free of charge, to any perso"
  },
  {
    "path": "README.md",
    "chars": 5330,
    "preview": "CIFS Flexvolume Plugin for Kubernetes\n=====================================\n\nDriver for [CIFS][1] (SMB, Samba, Windows S"
  },
  {
    "path": "cifs",
    "chars": 5277,
    "preview": "#!/bin/bash\n\nset -u\n\n# ====================================================================\n# Example configuration:\n# ="
  }
]

About this extraction

This page contains the full source code of the fstab/cifs GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 3 files (11.4 KB), approximately 3.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!