Refuse to create/resize volumes in case of insufficient disk space

This commit is contained in:
Mehran Kholdi 2021-07-02 20:31:01 +04:30
parent 50437acf16
commit 45d1ab1aa3
5 changed files with 43 additions and 11 deletions

View File

@ -35,7 +35,6 @@ Features
- [x] Direct I/O: Near-zero disk performance overhead - [x] Direct I/O: Near-zero disk performance overhead
- [x] Dynamic provisioning - [x] Dynamic provisioning
- [x] Enforced volume size limit - [x] Enforced volume size limit
- [x] Thin provisioned
- [x] Access Modes - [x] Access Modes
- [x] ReadWriteOnce - [x] ReadWriteOnce
- ~~ReadOnlyMany~~ - ~~ReadOnlyMany~~

View File

@ -4,3 +4,4 @@ PROVISIONER_NAME = os.getenv("PROVISIONER_NAME", "rawfile.csi.openebs.io")
PROVISIONER_VERSION = "0.5.0" PROVISIONER_VERSION = "0.5.0"
DATA_DIR = "/data" DATA_DIR = "/data"
CONFIG = {} CONFIG = {}
RESOURCE_EXHAUSTED_EXIT_CODE = 101

View File

@ -1,6 +1,7 @@
import json import json
import uuid import uuid
from pathlib import Path from pathlib import Path
from subprocess import CalledProcessError
from time import sleep from time import sleep
import pykube import pykube
@ -66,5 +67,8 @@ def run_on_node(fn, node):
wait_for(is_finished, "task to finish") wait_for(is_finished, "task to finish")
if task_pod.obj["status"]["phase"] != "Succeeded": if task_pod.obj["status"]["phase"] != "Succeeded":
raise Exception(f"Task {name} failed") exit_code = task_pod.obj["status"]["containerStatuses"][0]["state"][
"terminated"
]["exitCode"]
raise CalledProcessError(returncode=exit_code, cmd=f"Task: {name}")
task_pod.delete() task_pod.delete()

View File

@ -1,10 +1,11 @@
from pathlib import Path from pathlib import Path
from subprocess import CalledProcessError
import grpc import grpc
from google.protobuf.wrappers_pb2 import BoolValue from google.protobuf.wrappers_pb2 import BoolValue
import rawfile_util import rawfile_util
from consts import PROVISIONER_VERSION, PROVISIONER_NAME from consts import PROVISIONER_VERSION, PROVISIONER_NAME, RESOURCE_EXHAUSTED_EXIT_CODE
from csi import csi_pb2, csi_pb2_grpc from csi import csi_pb2, csi_pb2_grpc
from declarative import be_symlink, be_absent from declarative import be_symlink, be_absent
from fs_util import device_stats, mountpoint_to_dev from fs_util import device_stats, mountpoint_to_dev
@ -184,10 +185,18 @@ class RawFileControllerServicer(csi_pb2_grpc.ControllerServicer):
grpc.StatusCode.INVALID_ARGUMENT, "Topology key not found... why?" grpc.StatusCode.INVALID_ARGUMENT, "Topology key not found... why?"
) )
run_on_node( try:
init_rawfile.as_cmd(volume_id=request.name, size=size), run_on_node(
node=node_name, init_rawfile.as_cmd(volume_id=request.name, size=size),
) node=node_name,
)
except CalledProcessError as exc:
if exc.returncode == RESOURCE_EXHAUSTED_EXIT_CODE:
context.abort(
grpc.StatusCode.RESOURCE_EXHAUSTED, "Not enough disk space"
)
else:
raise exc
return csi_pb2.CreateVolumeResponse( return csi_pb2.CreateVolumeResponse(
volume=csi_pb2.Volume( volume=csi_pb2.Volume(
@ -210,9 +219,18 @@ class RawFileControllerServicer(csi_pb2_grpc.ControllerServicer):
volume_id = request.volume_id volume_id = request.volume_id
node_name = volume_to_node(volume_id) node_name = volume_to_node(volume_id)
size = request.capacity_range.required_bytes size = request.capacity_range.required_bytes
run_on_node(
expand_rawfile.as_cmd(volume_id=volume_id, size=size), node=node_name try:
) run_on_node(
expand_rawfile.as_cmd(volume_id=volume_id, size=size), node=node_name
)
except CalledProcessError as exc:
if exc.returncode == RESOURCE_EXHAUSTED_EXIT_CODE:
context.abort(
grpc.StatusCode.RESOURCE_EXHAUSTED, "Not enough disk space"
)
else:
raise exc
return csi_pb2.ControllerExpandVolumeResponse( return csi_pb2.ControllerExpandVolumeResponse(
capacity_bytes=size, capacity_bytes=size,

View File

@ -25,6 +25,10 @@ def init_rawfile(volume_id, size):
from pathlib import Path from pathlib import Path
from util import run from util import run
from consts import RESOURCE_EXHAUSTED_EXIT_CODE
if rawfile_util.get_capacity() < size:
exit(RESOURCE_EXHAUSTED_EXIT_CODE)
img_dir = rawfile_util.img_dir(volume_id) img_dir = rawfile_util.img_dir(volume_id)
img_dir.mkdir(exist_ok=True) img_dir.mkdir(exist_ok=True)
@ -47,11 +51,17 @@ def init_rawfile(volume_id, size):
@remote_fn @remote_fn
def expand_rawfile(volume_id, size): def expand_rawfile(volume_id, size):
import rawfile_util import rawfile_util
from util import run from util import run
from consts import RESOURCE_EXHAUSTED_EXIT_CODE
img_file = rawfile_util.img_file(volume_id) img_file = rawfile_util.img_file(volume_id)
if rawfile_util.metadata(volume_id)["size"] >= size: size_inc = size - rawfile_util.metadata(volume_id)["size"]
if size_inc <= 0:
return return
if rawfile_util.get_capacity() < size_inc:
exit(RESOURCE_EXHAUSTED_EXIT_CODE)
rawfile_util.patch_metadata( rawfile_util.patch_metadata(
volume_id, volume_id,
{"size": size}, {"size": size},