Refuse to create/resize volumes in case of insufficient disk space
This commit is contained in:
parent
50437acf16
commit
45d1ab1aa3
@ -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~~
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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?"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
run_on_node(
|
run_on_node(
|
||||||
init_rawfile.as_cmd(volume_id=request.name, size=size),
|
init_rawfile.as_cmd(volume_id=request.name, size=size),
|
||||||
node=node_name,
|
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
|
||||||
|
|
||||||
|
try:
|
||||||
run_on_node(
|
run_on_node(
|
||||||
expand_rawfile.as_cmd(volume_id=volume_id, size=size), node=node_name
|
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,
|
||||||
|
12
remote.py
12
remote.py
@ -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},
|
||||||
|
Loading…
Reference in New Issue
Block a user