feat(fs): remove JS based SMB handler

It's not well tested nor maintained.
This commit is contained in:
Julien Fontanet 2022-08-10 16:24:09 +02:00
parent 75a9799e96
commit b50e95802c
5 changed files with 15 additions and 195 deletions

View File

@ -24,7 +24,6 @@
"@aws-sdk/lib-storage": "^3.54.0", "@aws-sdk/lib-storage": "^3.54.0",
"@aws-sdk/middleware-apply-body-checksum": "^3.58.0", "@aws-sdk/middleware-apply-body-checksum": "^3.58.0",
"@aws-sdk/node-http-handler": "^3.54.0", "@aws-sdk/node-http-handler": "^3.54.0",
"@marsaud/smb2": "^0.18.0",
"@sindresorhus/df": "^3.1.1", "@sindresorhus/df": "^3.1.1",
"@vates/async-each": "^1.0.0", "@vates/async-each": "^1.0.0",
"@vates/coalesce-calls": "^0.1.0", "@vates/coalesce-calls": "^0.1.0",

View File

@ -5,7 +5,6 @@ import RemoteHandlerLocal from './local'
import RemoteHandlerNfs from './nfs' import RemoteHandlerNfs from './nfs'
import RemoteHandlerS3 from './s3' import RemoteHandlerS3 from './s3'
import RemoteHandlerSmb from './smb' import RemoteHandlerSmb from './smb'
import RemoteHandlerSmbMount from './smb-mount'
const HANDLERS = { const HANDLERS = {
file: RemoteHandlerLocal, file: RemoteHandlerLocal,
@ -15,10 +14,8 @@ const HANDLERS = {
try { try {
execa.sync('mount.cifs', ['-V']) execa.sync('mount.cifs', ['-V'])
HANDLERS.smb = RemoteHandlerSmbMount
} catch (_) {
HANDLERS.smb = RemoteHandlerSmb HANDLERS.smb = RemoteHandlerSmb
} } catch (_) {}
export const getHandler = (remote, ...rest) => { export const getHandler = (remote, ...rest) => {
const Handler = HANDLERS[parse(remote.url).type] const Handler = HANDLERS[parse(remote.url).type]

View File

@ -1,23 +0,0 @@
import { parse } from 'xo-remote-parser'
import MountHandler from './_mount'
import { normalize } from './path'
export default class SmbMountHandler extends MountHandler {
constructor(remote, opts) {
const { domain = 'WORKGROUP', host, password, path, username } = parse(remote.url)
super(remote, opts, {
type: 'cifs',
device: '//' + host + normalize(path),
options: `domain=${domain}`,
env: {
USER: username,
PASSWD: password,
},
})
}
get type() {
return 'smb'
}
}

View File

@ -1,163 +1,23 @@
import Smb2 from '@marsaud/smb2' import { parse } from 'xo-remote-parser'
import RemoteHandlerAbstract from './abstract' import MountHandler from './_mount'
import { normalize } from './path'
// Normalize the error code for file not found. export default class SmbHandler extends MountHandler {
const wrapError = (error, code) => ({
__proto__: error,
cause: error,
code,
})
const normalizeError = (error, shouldBeDirectory) => {
const { code } = error
throw code === 'STATUS_DIRECTORY_NOT_EMPTY'
? wrapError(error, 'ENOTEMPTY')
: code === 'STATUS_FILE_IS_A_DIRECTORY'
? wrapError(error, 'EISDIR')
: code === 'STATUS_NOT_A_DIRECTORY'
? wrapError(error, 'ENOTDIR')
: code === 'STATUS_OBJECT_NAME_NOT_FOUND' || code === 'STATUS_OBJECT_PATH_NOT_FOUND'
? wrapError(error, 'ENOENT')
: code === 'STATUS_OBJECT_NAME_COLLISION'
? wrapError(error, 'EEXIST')
: code === 'STATUS_NOT_SUPPORTED' || code === 'STATUS_INVALID_PARAMETER'
? wrapError(error, shouldBeDirectory ? 'ENOTDIR' : 'EISDIR')
: error
}
const normalizeDirError = error => normalizeError(error, true)
export default class SmbHandler extends RemoteHandlerAbstract {
constructor(remote, opts) { constructor(remote, opts) {
super(remote, opts) const { domain = 'WORKGROUP', host, password, path, username } = parse(remote.url)
super(remote, opts, {
// defined in _sync() type: 'cifs',
this._client = undefined device: '//' + host + normalize(path),
options: `domain=${domain}`,
const prefix = this._remote.path env: {
this._prefix = prefix !== '' ? prefix + '\\' : prefix USER: username,
PASSWD: password,
},
})
} }
get type() { get type() {
return 'smb' return 'smb'
} }
_getFilePath(file) {
return this._prefix + (typeof file === 'string' ? file : file.path).slice(1).replace(/\//g, '\\')
}
_dirname(file) {
const parts = file.split('\\')
parts.pop()
return parts.join('\\')
}
_closeFile(file) {
return this._client.close(file).catch(normalizeError)
}
_createReadStream(file, options) {
if (typeof file === 'string') {
file = this._getFilePath(file)
} else {
options = { autoClose: false, ...options, fd: file.fd }
file = ''
}
return this._client.createReadStream(file, options).catch(normalizeError)
}
_createWriteStream(file, options) {
if (typeof file === 'string') {
file = this._getFilePath(file)
} else {
options = { autoClose: false, ...options, fd: file.fd }
file = ''
}
return this._client.createWriteStream(file, options).catch(normalizeError)
}
_forget() {
const client = this._client
this._client = undefined
return client.disconnect()
}
_getSize(file) {
return this._client.getSize(this._getFilePath(file)).catch(normalizeError)
}
_list(dir) {
return this._client.readdir(this._getFilePath(dir)).catch(normalizeDirError)
}
_mkdir(dir, { mode }) {
return this._client.mkdir(this._getFilePath(dir), mode).catch(normalizeDirError)
}
// TODO: add flags
_openFile(path, flags) {
return this._client.open(this._getFilePath(path), flags).catch(normalizeError)
}
async _read(file, buffer, position) {
const client = this._client
const needsClose = typeof file === 'string'
file = needsClose ? await client.open(this._getFilePath(file)) : file.fd
try {
return await client.read(file, buffer, 0, buffer.length, position)
} catch (error) {
normalizeError(error)
} finally {
if (needsClose) {
await client.close(file)
}
}
}
_readFile(file, options) {
return this._client.readFile(this._getFilePath(file), options).catch(normalizeError)
}
_rename(oldPath, newPath) {
return this._client
.rename(this._getFilePath(oldPath), this._getFilePath(newPath), {
replace: true,
})
.catch(normalizeError)
}
_rmdir(dir) {
return this._client.rmdir(this._getFilePath(dir)).catch(normalizeDirError)
}
_sync() {
const remote = this._remote
this._client = new Smb2({
share: `\\\\${remote.host}`,
domain: remote.domain,
username: remote.username,
password: remote.password,
autoCloseTimeout: 0,
})
// Check access (smb2 does not expose connect in public so far...)
return this.list('.')
}
_truncate(file, len) {
return this._client.truncate(this._getFilePath(file), len).catch(normalizeError)
}
_unlink(file) {
return this._client.unlink(this._getFilePath(file)).catch(normalizeError)
}
_writeFd(file, buffer, position) {
return this._client.write(file.fd, buffer, 0, buffer.length, position)
}
_writeFile(file, data, options) {
return this._client.writeFile(this._getFilePath(file), data, options).catch(normalizeError)
}
} }

View File

@ -2365,14 +2365,6 @@
semver "^7.3.5" semver "^7.3.5"
tar "^6.1.11" tar "^6.1.11"
"@marsaud/smb2@^0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@marsaud/smb2/-/smb2-0.18.0.tgz#c5c859c2d4ab8ae16f195208bc71561f0a9b92ba"
integrity sha512-DxOVZCX0uDe3S9QQqXk6mnnQ7nEaqI5gPwuNQ7dDQCXY00Qp0CIa5N1LNYKCcW1DYTJceOvRvNujL5hgnQmqOA==
dependencies:
ntlm "~0.1.1"
readable-stream "^3.0.6"
"@mrmlnc/readdir-enhanced@^2.2.1": "@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@ -13302,11 +13294,6 @@ nth-check@^2.0.1:
dependencies: dependencies:
boolbase "^1.0.0" boolbase "^1.0.0"
ntlm@~0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/ntlm/-/ntlm-0.1.3.tgz#3b814ebc530a1e6cd712dcf0cf590155931195c1"
integrity sha512-pPlHxhAegZP4QAaOYd51vRd6VXTGfF7VLKJwuwN0iEB1aIi3SnqXYuS/bH/6wWBOq+Ehdil49mHm1Nseon085w==
num2fraction@^1.2.2: num2fraction@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"