Skip to content

Commit

Permalink
objectivefs refinement, better iscsi session handling
Browse files Browse the repository at this point in the history
Signed-off-by: Travis Glenn Hansen <travisghansen@yahoo.com>
  • Loading branch information
travisghansen committed Mar 2, 2024
1 parent d70b45b commit ed32cf8
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 114 deletions.
1 change: 1 addition & 0 deletions .github/bin/docker-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ if [[ -n "${IMAGE_TAG}" ]]; then
docker buildx build --progress plain --pull --push --platform "${DOCKER_BUILD_PLATFORM}" -t ${DOCKER_REPO}:${IMAGE_TAG} \
--label "org.opencontainers.image.created=$(date -u --iso-8601=seconds)" \
--label "org.opencontainers.image.revision=${GITHUB_SHA}" \
--build-arg OBJECTIVEFS_DOWNLOAD_ID=${OBJECTIVEFS_DOWNLOAD_ID} \
.
else
:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ jobs:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
GHCR_PASSWORD: ${{ secrets.GHCR_PASSWORD }}
OBJECTIVEFS_DOWNLOAD_ID: ${{ secrets.OBJECTIVEFS_DOWNLOAD_ID }}
DOCKER_CLI_EXPERIMENTAL: enabled
DOCKER_BUILD_PLATFORM: linux/amd64,linux/arm64,linux/arm/v7,linux/s390x,linux/ppc64le
IMAGE_TAG: ${{needs.determine-image-tag.outputs.tag}}
Expand Down
25 changes: 13 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ARG BUILDPLATFORM
RUN echo "I am running build on $BUILDPLATFORM, building for $TARGETPLATFORM"

RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8

ENV LANG=en_US.utf8
ENV NODE_VERSION=v20.11.1
Expand All @@ -26,8 +26,8 @@ ENV PATH=/usr/local/lib/nodejs/bin:$PATH

# Run as a non-root user
RUN useradd --create-home csi \
&& mkdir /home/csi/app \
&& chown -R csi: /home/csi
&& mkdir /home/csi/app \
&& chown -R csi: /home/csi
WORKDIR /home/csi/app
USER csi

Expand All @@ -50,21 +50,22 @@ ENV DEBIAN_FRONTEND=noninteractive

ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG OBJECTIVEFS_DOWNLOAD_ID

RUN echo "I am running on final $BUILDPLATFORM, building for $TARGETPLATFORM"

RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8

ENV LANG=en_US.utf8
ENV NODE_ENV=production

# Workaround for https://github.com/nodejs/node/issues/37219
RUN test $(uname -m) != armv7l || ( \
apt-get update \
&& apt-get install -y libatomic1 \
&& rm -rf /var/lib/apt/lists/* \
)
apt-get update \
&& apt-get install -y libatomic1 \
&& rm -rf /var/lib/apt/lists/* \
)

# install node
#ENV PATH=/usr/local/lib/nodejs/bin:$PATH
Expand All @@ -75,16 +76,16 @@ COPY --from=build /usr/local/lib/nodejs/bin/node /usr/local/bin/node
# netbase is required by rpcbind/rpcinfo to work properly
# /etc/{services,rpc} are required
RUN apt-get update && \
apt-get install -y wget netbase socat e2fsprogs exfatprogs xfsprogs btrfs-progs fatresize dosfstools ntfs-3g nfs-common cifs-utils fdisk gdisk cloud-guest-utils sudo rsync procps util-linux nvme-cli fuse && \
rm -rf /var/lib/apt/lists/*
apt-get install -y wget netbase socat e2fsprogs exfatprogs xfsprogs btrfs-progs fatresize dosfstools ntfs-3g nfs-common cifs-utils fdisk gdisk cloud-guest-utils sudo rsync procps util-linux nvme-cli fuse && \
rm -rf /var/lib/apt/lists/*

# controller requirements
#RUN apt-get update && \
# apt-get install -y ansible && \
# rm -rf /var/lib/apt/lists/*

# install objectivefs
ENV OBJECTIVEFS_VERSION=7.1
ENV OBJECTIVEFS_VERSION=7.2
ADD docker/objectivefs-installer.sh /usr/local/sbin
RUN chmod +x /usr/local/sbin/objectivefs-installer.sh && objectivefs-installer.sh

Expand Down Expand Up @@ -112,7 +113,7 @@ RUN chmod +x /usr/local/bin/oneclient

# Run as a non-root user
RUN useradd --create-home csi \
&& chown -R csi: /home/csi
&& chown -R csi: /home/csi

COPY --from=build --chown=csi:csi /home/csi/app /home/csi/app

Expand Down
2 changes: 1 addition & 1 deletion docker/objectivefs-installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export DEB_FILE="objectivefs_${OBJECTIVEFS_VERSION}_${OBJECTIVEFS_ARCH}.deb"

echo "I am installing objectivefs $OBJECTIVEFS_VERSION"

wget "https://objectivefs.com/user/download/ac24htfht/${DEB_FILE}"
wget "https://objectivefs.com/user/download/${OBJECTIVEFS_DOWNLOAD_ID}/${DEB_FILE}"
dpkg -i "${DEB_FILE}"

rm "${DEB_FILE}"
82 changes: 0 additions & 82 deletions src/driver/controller-objectivefs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -592,75 +592,6 @@ class ControllerObjectiveFSDriver extends CsiBaseDriver {
grpc.status.UNIMPLEMENTED,
`operation not supported by driver`
);

const driver = this;

// both these are required
let source_volume_id = call.request.source_volume_id;
let name = call.request.name;

if (!source_volume_id) {
throw new GrpcError(
grpc.status.INVALID_ARGUMENT,
`snapshot source_volume_id is required`
);
}

source_volume_id = source_volume_id.toLowerCase();

if (!name) {
throw new GrpcError(
grpc.status.INVALID_ARGUMENT,
`snapshot name is required`
);
}

driver.ctx.logger.verbose("requested snapshot name: %s", name);

let invalid_chars;
invalid_chars = name.match(/[^a-z0-9_\-:.+]+/gi);
if (invalid_chars) {
invalid_chars = String.prototype.concat(
...new Set(invalid_chars.join(""))
);
throw new GrpcError(
grpc.status.INVALID_ARGUMENT,
`snapshot name contains invalid characters: ${invalid_chars}`
);
}

// https://stackoverflow.com/questions/32106243/regex-to-remove-all-non-alpha-numeric-and-replace-spaces-with/32106277
name = name.replace(/[^a-z0-9_\-:.+]+/gi, "");

driver.ctx.logger.verbose("cleansed snapshot name: %s", name);

const snapshot_id = `${source_volume_id}-${name}`;
const volume_path = driver.getControllerVolumePath(source_volume_id);
const snapshot_path = driver.getControllerSnapshotPath(snapshot_id);

// do NOT overwrite existing snapshot
if (!(await driver.directoryExists(snapshot_path))) {
await driver.cloneDir(volume_path, snapshot_path);
}

let size_bytes = await driver.getDirectoryUsage(snapshot_path);
return {
snapshot: {
/**
* The purpose of this field is to give CO guidance on how much space
* is needed to create a volume from this snapshot.
*/
size_bytes,
snapshot_id,
source_volume_id: source_volume_id,
//https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto
creation_time: {
seconds: Math.round(new Date().getTime() / 1000),
nanos: 0,
},
ready_to_use: true,
},
};
}

/**
Expand All @@ -674,19 +605,6 @@ class ControllerObjectiveFSDriver extends CsiBaseDriver {
grpc.status.UNIMPLEMENTED,
`operation not supported by driver`
);

const driver = this;

const snapshot_id = call.request.snapshot_id;

if (!snapshot_id) {
throw new GrpcError(
grpc.status.INVALID_ARGUMENT,
`snapshot_id is required`
);
}

return {};
}

/**
Expand Down
26 changes: 20 additions & 6 deletions src/driver/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1265,19 +1265,18 @@ class CsiBaseDriver {
let objectivefs = driver.getDefaultObjectiveFSInstance();
let ofs_filesystem = volume_context.filesystem;
let env = {};
for (const key in volume_context) {
if (key.startsWith("env.")) {
env[key.substr("env.".length)] = volume_context[key];
}
}

for (const key in normalizedSecrets) {
if (key.startsWith("env.")) {
env[key.substr("env.".length)] = normalizedSecrets[key];
}
}

let ofs_object_store = env["OBJECTSTORE"];
for (const key in volume_context) {
if (key.startsWith("env.")) {
env[key.substr("env.".length)] = volume_context[key];
}
}

if (!ofs_filesystem) {
throw new GrpcError(
Expand All @@ -1286,13 +1285,28 @@ class CsiBaseDriver {
);
}

let ofs_object_store = env["OBJECTSTORE"];
if (!ofs_object_store) {
ofs_object_store = await objectivefs.getObjectStoreFromFilesystem(
ofs_filesystem
);
if (ofs_object_store) {
env["OBJECTSTORE"] = ofs_object_store;
}
}

if (!ofs_object_store) {
throw new GrpcError(
grpc.status.FAILED_PRECONDITION,
`missing required ofs volume env.OBJECTSTORE`
);
}

// normalize fs to not include objectstore
ofs_filesystem = await objectivefs.stripObjectStoreFromFilesystem(
ofs_filesystem
);

device = `${ofs_object_store}${ofs_filesystem}`;
result = await mount.deviceIsMountedAtPath(
device,
Expand Down
16 changes: 16 additions & 0 deletions src/utils/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,20 @@ function stringify(value) {
return JSON.stringify(value, getCircularReplacer());
}

function before_string(target, search) {
if (!target.includes(search)) {
return "";
}
return target.substring(0, target.indexOf(search));
}

function after_string(target, search) {
if (!target.includes(search)) {
return "";
}
return target.substring(target.indexOf(search) + search.length);
}

function default_supported_block_filesystems() {
return ["btrfs", "exfat", "ext3", "ext4", "ext4dev", "ntfs", "vfat", "xfs"];
}
Expand Down Expand Up @@ -266,6 +280,8 @@ module.exports.crc8 = crc8;
module.exports.lockKeysFromRequest = lockKeysFromRequest;
module.exports.getLargestNumber = getLargestNumber;
module.exports.stringify = stringify;
module.exports.before_string = before_string;
module.exports.after_string = after_string;
module.exports.stripWindowsDriveLetter = stripWindowsDriveLetter;
module.exports.hasWindowsDriveLetter = hasWindowsDriveLetter;
module.exports.axios_request = axios_request;
Expand Down
27 changes: 25 additions & 2 deletions src/utils/iscsi.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const cp = require("child_process");
const { sleep } = require("./general");
const { hostname_lookup, sleep } = require("./general");
const net = require("net");

function getIscsiValue(value) {
if (value == "<empty>") return null;
Expand Down Expand Up @@ -179,12 +180,34 @@ class ISCSI {
const sessions = await iscsi.iscsiadm.getSessions();

let parsedPortal = iscsi.parsePortal(portal);
let parsedPortalHostIP = "";
if (parsedPortal.host) {
// if host is not an ip address
if (net.isIP(parsePortal.host) == 0) {
// ipv6 response is without []
parsedPortalHostIP =
(await hostname_lookup(parsedPortal.host)) || "";
}
}

// set invalid hostname/ip string to ensure empty values do not errantly pass
if (!parsedPortalHostIP) {
parsedPortalHostIP = "--------------------------------------";
}
let session = false;
sessions.every((i_session) => {
// [2a10:4741:36:28:e61d:2dff:fe90:80fe]:3260
// i_session.portal includes [] for ipv6
if (
`${i_session.iqn}` == tgtIQN &&
(portal == i_session.portal ||
`[${parsedPortal.host}]:${parsedPortal.port}` == i_session.portal)
`${parsedPortal.host}:${parsedPortal.port}` == i_session.portal ||
`${parsedPortalHostIP}:${parsedPortal.port}` ==
i_session.portal ||
`[${parsedPortal.host}]:${parsedPortal.port}` ==
i_session.portal ||
`[${parsedPortalHostIP}]:${parsedPortal.port}` ==
i_session.portal)
) {
session = i_session;
return false;
Expand Down

0 comments on commit ed32cf8

Please sign in to comment.