This commit is contained in:
Danil Uzlov 2025-05-14 17:17:17 +07:00 committed by GitHub
commit b4523d9370
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 52 additions and 6 deletions

View File

@ -486,6 +486,21 @@ const signalMapping = {
} }
} }
if (driver && typeof driver.getCleanupHandlers === 'function') {
const cleanup = driver.getCleanupHandlers();
console.log(`running driver ${cleanup.length} cleanup handlers`);
for (const c of cleanup) {
try {
c();
} catch (e) {
console.log("cleanup handler failed");
console.log(e);
}
}
} else {
console.log(`current driver does not support cleanup`);
}
console.log("server fully shutdown, exiting"); console.log("server fully shutdown, exiting");
process.exit(codeNumber); process.exit(codeNumber);
}); });

View File

@ -113,19 +113,27 @@ class ControllerClientCommonDriver extends CsiBaseDriver {
} }
} }
if (this.ctx.args.csiMode.includes("controller")) { if (this.ctx.args.csiMode.includes("controller") && !options.disableBackgroundSnapshotChecks) {
setInterval(() => { let cutCheckIndex = setInterval(() => {
if (SNAPSHOTS_CUT_IN_FLIGHT.size == 0) {
return;
}
this.ctx.logger.info("snapshots cut in flight", { this.ctx.logger.info("snapshots cut in flight", {
names: [...SNAPSHOTS_CUT_IN_FLIGHT], names: [...SNAPSHOTS_CUT_IN_FLIGHT],
count: SNAPSHOTS_CUT_IN_FLIGHT.size, count: SNAPSHOTS_CUT_IN_FLIGHT.size,
}); });
}, 30 * 1000); }, 30 * 1000);
setInterval(() => { this.cleanup.push(() => clearInterval(cutCheckIndex));
let restoreCheckIndex = setInterval(() => {
if (SNAPSHOTS_RESTORE_IN_FLIGHT.size == 0) {
return;
}
this.ctx.logger.info("snapshots restore in flight", { this.ctx.logger.info("snapshots restore in flight", {
names: [...SNAPSHOTS_RESTORE_IN_FLIGHT], names: [...SNAPSHOTS_RESTORE_IN_FLIGHT],
count: SNAPSHOTS_RESTORE_IN_FLIGHT.size, count: SNAPSHOTS_RESTORE_IN_FLIGHT.size,
}); });
}, 30 * 1000); }, 30 * 1000);
this.cleanup.push(() => clearInterval(restoreCheckIndex));
} }
} }

View File

@ -16,10 +16,12 @@ class ControllerZfsGenericDriver extends ControllerZfsBaseDriver {
getExecClient() { getExecClient() {
return this.ctx.registry.get(`${__REGISTRY_NS__}:exec_client`, () => { return this.ctx.registry.get(`${__REGISTRY_NS__}:exec_client`, () => {
if (this.options.sshConnection) { if (this.options.sshConnection) {
return new SshClient({ const sshClient = new SshClient({
logger: this.ctx.logger, logger: this.ctx.logger,
connection: this.options.sshConnection, connection: this.options.sshConnection,
}); });
this.cleanup.push(() => sshClient.finalize());
return sshClient;
} else { } else {
return new LocalCliExecClient({ return new LocalCliExecClient({
logger: this.ctx.logger, logger: this.ctx.logger,

View File

@ -57,10 +57,12 @@ class FreeNASSshDriver extends ControllerZfsBaseDriver {
getExecClient() { getExecClient() {
return this.ctx.registry.get(`${__REGISTRY_NS__}:exec_client`, () => { return this.ctx.registry.get(`${__REGISTRY_NS__}:exec_client`, () => {
return new SshClient({ const sshClient = new SshClient({
logger: this.ctx.logger, logger: this.ctx.logger,
connection: this.options.sshConnection, connection: this.options.sshConnection,
}); });
this.cleanup.push(() => sshClient.finalize());
return sshClient;
}); });
} }

View File

@ -33,6 +33,7 @@ class CsiBaseDriver {
constructor(ctx, options) { constructor(ctx, options) {
this.ctx = ctx; this.ctx = ctx;
this.options = options || {}; this.options = options || {};
this.cleanup = [];
if (!this.options.hasOwnProperty("node")) { if (!this.options.hasOwnProperty("node")) {
this.options.node = {}; this.options.node = {};
@ -51,6 +52,10 @@ class CsiBaseDriver {
} }
} }
getCleanupHandlers() {
return this.cleanup;
}
/** /**
* abstract way of retrieving values from parameters/secrets * abstract way of retrieving values from parameters/secrets
* in order of preference: * in order of preference:

View File

@ -125,10 +125,12 @@ class ZfsLocalEphemeralInlineDriver extends CsiBaseDriver {
getSshClient() { getSshClient() {
return this.ctx.registry.get(`${__REGISTRY_NS__}:ssh_client`, () => { return this.ctx.registry.get(`${__REGISTRY_NS__}:ssh_client`, () => {
return new SshClient({ const sshClient = new SshClient({
logger: this.ctx.logger, logger: this.ctx.logger,
connection: this.options.sshConnection, connection: this.options.sshConnection,
}); });
this.cleanup.push(() => sshClient.finalize());
return sshClient;
}); });
} }

View File

@ -75,8 +75,14 @@ class SshClient {
const start_error_event_count = this.error_event_count; const start_error_event_count = this.error_event_count;
try { try {
await this.conn_mutex.runExclusive(async () => { await this.conn_mutex.runExclusive(async () => {
if (this.finalized) {
throw 'using finalized ssh client';
}
this.conn.connect(this.options.connection); this.conn.connect(this.options.connection);
do { do {
if (this.finalized) {
throw 'ssh client finalized during connection';
}
if (start_error_event_count != this.error_event_count) { if (start_error_event_count != this.error_event_count) {
throw this.conn_err; throw this.conn_err;
} }
@ -104,6 +110,12 @@ class SshClient {
return this._connect(); return this._connect();
} }
finalize() {
this.finalized = true;
const conn = this.conn;
conn.end();
}
async exec(command, options = {}, stream_proxy = null) { async exec(command, options = {}, stream_proxy = null) {
// default is to reuse // default is to reuse
if (process.env.SSH_REUSE_CONNECTION == "0") { if (process.env.SSH_REUSE_CONNECTION == "0") {