From 0be4bce96fa5144df68f06bbb3395f4e3c12581b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Helberg?= Date: Thu, 21 Jul 2022 12:21:17 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + .tool-versions | 1 + Dockerfile | 12 +++ README.md | 6 ++ __pycache__/csi_pb2.cpython-310.pyc | Bin 0 -> 31009 bytes __pycache__/csi_pb2_grpc.cpython-310.pyc | Bin 0 -> 15872 bytes bin/build.sh | 3 + bin/gen-protos.sh | 3 + bin/push.sh | 3 + gluster-dir-csi.nomad | 58 +++++++++++ main.py | 126 +++++++++++++++++++++++ requirements.txt | 5 + test_part1.sh | 2 + 13 files changed, 221 insertions(+) create mode 100644 .gitignore create mode 100644 .tool-versions create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 __pycache__/csi_pb2.cpython-310.pyc create mode 100644 __pycache__/csi_pb2_grpc.cpython-310.pyc create mode 100755 bin/build.sh create mode 100755 bin/gen-protos.sh create mode 100755 bin/push.sh create mode 100644 gluster-dir-csi.nomad create mode 100644 main.py create mode 100644 requirements.txt create mode 100755 test_part1.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00219ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +csi_pb2.py +csi_pb2_grpc.py diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..85cfd4b --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +python 3.10.5 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d653c02 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.10-slim-bullseye + +RUN apt-get update -yq && \ + apt-get install -y --no-install-recommends glusterfs-client + +COPY requirements.txt / +RUN pip install --upgrade pip +RUN pip install -r /requirements.txt +RUN pip3 install -r /requirements.txt +COPY *.py / +RUN mkdir /csi +CMD python3 -u /main.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..d98a68a --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Intro + +This is a super alpha implementation that supports the CSI spec for directories on a gluster volume. +Each top level directory is treated as a volume. + +Currently tested on hashicorp nomad. diff --git a/__pycache__/csi_pb2.cpython-310.pyc b/__pycache__/csi_pb2.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e38a390561de09190b44288a07da7247f4d8a0bc GIT binary patch literal 31009 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