Support custom fsTypes

Test Plan:
- Deploy using `feature-fstype` image tag
- Create the following storage class:
```
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: btrfs-sc
parameters:
  fsType: btrfs
provisioner: rawfile.hamravesh.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
```
- Create and use a pvc backed by the new storage class
- Exec into the pod and verify that the mounted volume is a `btrfs` filesystem indeed

Reviewers: h.marvi, sina_rad, mhyousefi, bghadiri

Reviewed By: h.marvi, mhyousefi, bghadiri

Differential Revision: https://phab.hamravesh.ir/D833
This commit is contained in:
Mehran Kholdi 2020-07-12 22:17:29 +04:30
parent 0095c0e83a
commit 77862b85e2
6 changed files with 35 additions and 7 deletions

View File

@ -4,6 +4,9 @@ SnapshotClass:
FromName: true FromName: true
DriverInfo: DriverInfo:
Name: rawfile.hamravesh.com Name: rawfile.hamravesh.com
SupportedFsType:
ext4:
btrfs:
Capabilities: Capabilities:
persistence: true persistence: true
block: false block: false

View File

@ -4,6 +4,10 @@ FROM python:3.8.3-slim-buster
WORKDIR /app/ WORKDIR /app/
RUN apt-get update && \
apt-get install -y e2fsprogs btrfs-progs && \
rm -rf /var/lib/apt/lists/*
ENV PIP_NO_CACHE_DIR 1 ENV PIP_NO_CACHE_DIR 1
ADD ./requirements.txt ./ ADD ./requirements.txt ./
RUN pip install -r ./requirements.txt RUN pip install -r ./requirements.txt

View File

@ -40,7 +40,7 @@ Features
- [x] `Filesystem` mode - [x] `Filesystem` mode
- [ ] `Block` mode - [ ] `Block` mode
- [x] Volume metrics - [x] Volume metrics
- [ ] Supports fsTypes - [x] Supports fsTypes: `ext4`, `btrfs`
- [x] Online expansion: If fs supports it (e.g. ext4, btrfs) - [x] Online expansion: If fs supports it (e.g. ext4, btrfs)
- [ ] Online shrinking: If fs supports it (e.g. btrfs) - [ ] Online shrinking: If fs supports it (e.g. btrfs)
- [ ] Offline expansion/shrinking - [ ] Offline expansion/shrinking

View File

@ -108,12 +108,18 @@ class RawFileNodeServicer(csi_pb2_grpc.NodeServicer):
@log_grpc_request @log_grpc_request
def NodeExpandVolume(self, request, context): def NodeExpandVolume(self, request, context):
volume_id = request.volume_id volume_id = request.volume_id
volume_path = request.volume_path
size = request.capacity_range.required_bytes size = request.capacity_range.required_bytes
fs_type = rawfile_util.metadata(volume_id)["fs_type"]
img_file = rawfile_util.img_file(volume_id) img_file = rawfile_util.img_file(volume_id)
for dev in rawfile_util.attached_loops(img_file): for dev in rawfile_util.attached_loops(img_file):
run(f"losetup -c {dev}") run(f"losetup -c {dev}")
if True: # TODO: is ext2/ext3/ext4 if fs_type == "ext4":
run(f"resize2fs {dev}") run(f"resize2fs {dev}")
elif fs_type == "btrfs":
run(f"btrfs filesystem resize max {volume_path}")
else:
raise Exception(f"Unsupported fsType: {fs_type}")
break break
return csi_pb2.NodeExpandVolumeResponse(capacity_bytes=size) return csi_pb2.NodeExpandVolumeResponse(capacity_bytes=size)
@ -151,7 +157,9 @@ class RawFileControllerServicer(csi_pb2_grpc.ControllerServicer):
access_type = volume_capability.WhichOneof("access_type") access_type = volume_capability.WhichOneof("access_type")
if access_type == "mount": if access_type == "mount":
pass fs_type = volume_capability.mount.fs_type
if fs_type == "":
fs_type = "ext4"
elif access_type == "block": elif access_type == "block":
context.abort( context.abort(
grpc.StatusCode.INVALID_ARGUMENT, "Block mode not supported (yet)" grpc.StatusCode.INVALID_ARGUMENT, "Block mode not supported (yet)"
@ -179,7 +187,8 @@ class RawFileControllerServicer(csi_pb2_grpc.ControllerServicer):
) )
run_on_node( run_on_node(
init_rawfile.as_cmd(volume_id=request.name, size=size), node=node_name init_rawfile.as_cmd(volume_id=request.name, size=size, fs_type=fs_type),
node=node_name,
) )
return csi_pb2.CreateVolumeResponse( return csi_pb2.CreateVolumeResponse(

View File

@ -10,7 +10,7 @@ def scrub(volume_id):
@remote_fn @remote_fn
def init_rawfile(volume_id, size): def init_rawfile(volume_id, size, fs_type):
import time import time
import rawfile_util import rawfile_util
from volume_schema import LATEST_SCHEMA_VERSION from volume_schema import LATEST_SCHEMA_VERSION
@ -31,10 +31,16 @@ def init_rawfile(volume_id, size):
"created_at": time.time(), "created_at": time.time(),
"img_file": img_file.as_posix(), "img_file": img_file.as_posix(),
"size": size, "size": size,
"fs_type": fs_type,
}, },
) )
run(f"truncate -s {size} {img_file}") run(f"truncate -s {size} {img_file}")
if fs_type == "ext4":
run(f"mkfs.ext4 {img_file}") run(f"mkfs.ext4 {img_file}")
elif fs_type == "btrfs":
run(f"mkfs.btrfs {img_file}")
else:
raise Exception(f"Unsupported fsType: {fs_type}")
@remote_fn @remote_fn

View File

@ -1,6 +1,6 @@
import sys import sys
LATEST_SCHEMA_VERSION = 1 # type: int LATEST_SCHEMA_VERSION = 2 # type: int
def migrate_0_to_1(data: dict) -> dict: def migrate_0_to_1(data: dict) -> dict:
@ -8,6 +8,12 @@ def migrate_0_to_1(data: dict) -> dict:
return data return data
def migrate_1_to_2(data: dict) -> dict:
data["schema_version"] = 2
data.setdefault("fs_type", "ext4")
return data
def migrate_to(data: dict, version: int) -> dict: def migrate_to(data: dict, version: int) -> dict:
current = data.get("schema_version", 0) current = data.get("schema_version", 0)
if current > version: if current > version: