Compare commits
7 Commits
lite/neste
...
nr-fix-S3-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3c5efdd38 | ||
|
|
e00270e916 | ||
|
|
d17fd2dc11 | ||
|
|
a69d32de75 | ||
|
|
5040ce87e1 | ||
|
|
b7481f42cd | ||
|
|
2329705ad7 |
@@ -29,6 +29,7 @@
|
||||
"get-stream": "^6.0.0",
|
||||
"limit-concurrency-decorator": "^0.5.0",
|
||||
"lodash": "^4.17.4",
|
||||
"minio": "^7.0.18",
|
||||
"promise-toolbox": "^0.19.2",
|
||||
"proper-lockfile": "^4.1.2",
|
||||
"readable-stream": "^3.0.6",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import aws from '@sullux/aws-sdk'
|
||||
import assert from 'assert'
|
||||
import http from 'http'
|
||||
import https from 'https'
|
||||
import { Client as Minio } from 'minio'
|
||||
import { parse } from 'xo-remote-parser'
|
||||
|
||||
import RemoteHandlerAbstract from './abstract'
|
||||
@@ -10,13 +11,10 @@ import RemoteHandlerAbstract from './abstract'
|
||||
// limits: https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html
|
||||
const MIN_PART_SIZE = 1024 * 1024 * 5 // 5MB
|
||||
const MAX_PART_SIZE = 1024 * 1024 * 1024 * 5 // 5GB
|
||||
const MAX_PARTS_COUNT = 10000
|
||||
const MAX_OBJECT_SIZE = 1024 * 1024 * 1024 * 1024 * 5 // 5TB
|
||||
const IDEAL_FRAGMENT_SIZE = Math.ceil(MAX_OBJECT_SIZE / MAX_PARTS_COUNT) // the smallest fragment size that still allows a 5TB upload in 10000 fragments, about 524MB
|
||||
export default class S3Handler extends RemoteHandlerAbstract {
|
||||
constructor(remote, _opts) {
|
||||
super(remote)
|
||||
const { host, path, username, password, protocol, region } = parse(remote.url)
|
||||
const { host, hostname, port, path, username, password, protocol, region } = parse(remote.url)
|
||||
const params = {
|
||||
accessKeyId: username,
|
||||
apiVersion: '2006-03-01',
|
||||
@@ -29,8 +27,12 @@ export default class S3Handler extends RemoteHandlerAbstract {
|
||||
},
|
||||
}
|
||||
if (protocol === 'http') {
|
||||
params.httpOptions.agent = new http.Agent()
|
||||
params.sslEnabled = false
|
||||
throw new Error('HTTP no longer supported, please use HTTPS')
|
||||
} else {
|
||||
params.httpOptions.agent = new https.Agent({
|
||||
// TODO : UI checkbox
|
||||
rejectUnauthorized: false,
|
||||
})
|
||||
}
|
||||
if (region !== undefined) {
|
||||
params.region = region
|
||||
@@ -38,6 +40,15 @@ export default class S3Handler extends RemoteHandlerAbstract {
|
||||
|
||||
this._s3 = aws(params).s3
|
||||
|
||||
this._minioClient = new Minio({
|
||||
endPoint: hostname,
|
||||
port: port !== undefined ? +port : undefined,
|
||||
useSSL: protocol !== 'http',
|
||||
accessKey: username,
|
||||
secretKey: password,
|
||||
})
|
||||
// TODO : UI checkbox
|
||||
this._minioClient.setRequestOptions({ rejectUnauthorized: false })
|
||||
const splitPath = path.split('/').filter(s => s.length)
|
||||
this._bucket = splitPath.shift()
|
||||
this._dir = splitPath.join('/')
|
||||
@@ -73,13 +84,7 @@ export default class S3Handler extends RemoteHandlerAbstract {
|
||||
}
|
||||
|
||||
async _outputStream(path, input, { validator }) {
|
||||
await this._s3.upload(
|
||||
{
|
||||
...this._createParams(path),
|
||||
Body: input,
|
||||
},
|
||||
{ partSize: IDEAL_FRAGMENT_SIZE, queueSize: 1 }
|
||||
)
|
||||
await this._minioClient.putObject(this._bucket, this._dir + path, input)
|
||||
if (validator !== undefined) {
|
||||
try {
|
||||
await validator.call(this, path)
|
||||
|
||||
@@ -43,6 +43,8 @@ export const parse = string => {
|
||||
object.type = 's3'
|
||||
object.region = parsed.hash.length === 0 ? undefined : parsed.hash.slice(1) // remove '#'
|
||||
object.host = parsed.host
|
||||
object.port = parsed.port
|
||||
object.hostname = parsed.hostname
|
||||
object.path = parsed.pathname
|
||||
object.username = parsed.username
|
||||
object.password = decodeURIComponent(parsed.password)
|
||||
|
||||
@@ -3,7 +3,6 @@ import ActionButton from 'action-button'
|
||||
import decorate from 'apply-decorators'
|
||||
import Icon from 'icon'
|
||||
import React from 'react'
|
||||
import Tooltip from 'tooltip'
|
||||
import { addSubscriptions, resolveId } from 'utils'
|
||||
import { alert, confirm } from 'modal'
|
||||
import { createRemote, editRemote, subscribeRemotes } from 'xo'
|
||||
@@ -12,7 +11,7 @@ import { format } from 'xo-remote-parser'
|
||||
import { generateId, linkState } from 'reaclette-utils'
|
||||
import { injectState, provideState } from 'reaclette'
|
||||
import { map, some, trimStart } from 'lodash'
|
||||
import { Password, Number, Toggle } from 'form'
|
||||
import { Password, Number } from 'form'
|
||||
import { SelectProxy } from 'select-objects'
|
||||
|
||||
const remoteTypes = {
|
||||
@@ -40,7 +39,6 @@ export default decorate([
|
||||
username: undefined,
|
||||
directory: undefined,
|
||||
bucket: undefined,
|
||||
protocol: undefined,
|
||||
region: undefined,
|
||||
}),
|
||||
effects: {
|
||||
@@ -63,7 +61,6 @@ export default decorate([
|
||||
proxyId = remote.proxy,
|
||||
type = remote.type,
|
||||
username = remote.username,
|
||||
protocol = remote.protocol || 'https',
|
||||
region = remote.region,
|
||||
} = state
|
||||
let { path = remote.path } = state
|
||||
@@ -81,7 +78,7 @@ export default decorate([
|
||||
port: port || undefined,
|
||||
type,
|
||||
username,
|
||||
protocol,
|
||||
protocol: 'https',
|
||||
region,
|
||||
}),
|
||||
options: options !== '' ? options : null,
|
||||
@@ -140,9 +137,6 @@ export default decorate([
|
||||
setSecretKey(_, { target: { value } }) {
|
||||
this.state.password = value
|
||||
},
|
||||
setInsecure(_, value) {
|
||||
this.state.protocol = value ? 'http' : 'https'
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
formId: generateId,
|
||||
@@ -159,7 +153,6 @@ export default decorate([
|
||||
name = remote.name || '',
|
||||
options = remote.options || '',
|
||||
password = remote.password || '',
|
||||
protocol = remote.protocol || 'https',
|
||||
region = remote.region || '',
|
||||
parsedPath,
|
||||
path = parsedPath || '',
|
||||
@@ -339,11 +332,7 @@ export default decorate([
|
||||
{type === 's3' && (
|
||||
<fieldset className='form-group form-group'>
|
||||
<div className='input-group form-group'>
|
||||
<span className='input-group-addon'>
|
||||
<Tooltip content={formatMessage(messages.remoteS3TooltipProtocol)}>
|
||||
<Toggle iconSize={1} onChange={effects.setInsecure} value={protocol === 'http'} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
<em className='text-warning'>HTTP support has been removed, only HTTPS is supported</em>
|
||||
<input
|
||||
className='form-control'
|
||||
name='host'
|
||||
|
||||
61
yarn.lock
61
yarn.lock
@@ -2717,6 +2717,11 @@ async@^2.6.2, async@~2.6.3:
|
||||
dependencies:
|
||||
lodash "^4.17.14"
|
||||
|
||||
async@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
|
||||
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
@@ -3083,6 +3088,13 @@ bl@^4.0.3:
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
block-stream2@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/block-stream2/-/block-stream2-2.1.0.tgz#ac0c5ef4298b3857796e05be8ebed72196fa054b"
|
||||
integrity sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==
|
||||
dependencies:
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
block-stream@*:
|
||||
version "0.0.9"
|
||||
resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
|
||||
@@ -6076,6 +6088,11 @@ es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@
|
||||
es6-symbol "~3.1.3"
|
||||
next-tick "~1.0.0"
|
||||
|
||||
es6-error@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
||||
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
||||
|
||||
es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
||||
@@ -6789,7 +6806,7 @@ fast-safe-stringify@^2.0.7:
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
fast-xml-parser@^3.17.4:
|
||||
fast-xml-parser@^3.17.4, fast-xml-parser@^3.17.5:
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01"
|
||||
integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==
|
||||
@@ -9881,6 +9898,11 @@ json-stable-stringify@~0.0.0:
|
||||
dependencies:
|
||||
jsonify "~0.0.0"
|
||||
|
||||
json-stream@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-stream/-/json-stream-1.0.0.tgz#1a3854e28d2bbeeab31cc7ddf683d2ddc5652708"
|
||||
integrity sha1-GjhU4o0rvuqzHMfd9oPS3cVlJwg=
|
||||
|
||||
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
@@ -11112,6 +11134,11 @@ mime-db@1.47.0, "mime-db@>= 1.43.0 < 2":
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
|
||||
integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
|
||||
|
||||
mime-db@1.48.0:
|
||||
version "1.48.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d"
|
||||
integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==
|
||||
|
||||
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
|
||||
version "2.1.30"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
|
||||
@@ -11119,6 +11146,13 @@ mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.17, mime-types@~2.1.19,
|
||||
dependencies:
|
||||
mime-db "1.47.0"
|
||||
|
||||
mime-types@^2.1.14:
|
||||
version "2.1.31"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b"
|
||||
integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==
|
||||
dependencies:
|
||||
mime-db "1.48.0"
|
||||
|
||||
mime@1.6.0, mime@^1.4.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
@@ -11195,6 +11229,24 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
minio@^7.0.18:
|
||||
version "7.0.18"
|
||||
resolved "https://registry.yarnpkg.com/minio/-/minio-7.0.18.tgz#a2a6dae52a4dde9e35ed47cdf2accc21df4a512d"
|
||||
integrity sha512-jVRjkw8A5Spf+ETY5OXQUcQckHriuUA3u2+MAcX36btLT8EytlOVivxIseXvyFf9cNn3dy5w1F1UyjMvHU+nqg==
|
||||
dependencies:
|
||||
async "^3.1.0"
|
||||
block-stream2 "^2.0.0"
|
||||
es6-error "^4.1.1"
|
||||
fast-xml-parser "^3.17.5"
|
||||
json-stream "^1.0.0"
|
||||
lodash "^4.17.20"
|
||||
mime-types "^2.1.14"
|
||||
mkdirp "^0.5.1"
|
||||
querystring "0.2.0"
|
||||
through2 "^3.0.1"
|
||||
xml "^1.0.0"
|
||||
xml2js "^0.4.15"
|
||||
|
||||
minipass@^3.0.0:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
|
||||
@@ -17718,7 +17770,7 @@ xml2js@0.4.19:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~9.0.1"
|
||||
|
||||
xml2js@^0.4.19, xml2js@^0.4.23:
|
||||
xml2js@^0.4.15, xml2js@^0.4.19, xml2js@^0.4.23:
|
||||
version "0.4.23"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
|
||||
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
|
||||
@@ -17726,6 +17778,11 @@ xml2js@^0.4.19, xml2js@^0.4.23:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~11.0.0"
|
||||
|
||||
xml@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
|
||||
integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
|
||||
|
||||
xmlbuilder@8.2.x:
|
||||
version "8.2.2"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773"
|
||||
|
||||
Reference in New Issue
Block a user