Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ SIGNOZ_BASE_URL=
SIGNOZ_SERVICE_NAME=fastgpt-plugin

# S3 Config
# Customize S3 Endpoint. Such as https://example.com The URL returned will be rewrite by this Endpoint: https://example.com/{{filename}}
# Customize S3 Base URL, for example: https://s3.example.com, make sure you can access your files via https://s3.example.com/[bucket]/[objectname]
S3_EXTERNAL_BASE_URL=
S3_ENDPOINT=localhost
S3_PORT=9000
S3_USE_SSL=false
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_UPLOAD_BUCKET=files # 系统工具,创建的临时文件,存储的桶,要求公开读私有写。
S3_PLUGIN_BUCKET=fastgpt-plugin # 系统插件热安装文件都桶,私有读写。
S3_PLUGIN_BUCKET=fastgpt-plugin # 系统插件热安装文件的桶,私有读写。

# Signoz
SIGNOZ_BASE_URL=
Expand Down
1 change: 1 addition & 0 deletions modules/tool/api/upload/confirmUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default s.route(contract.tool.upload.confirmUpload, async ({ body }) => {

await mongoSessionRun(async (session) => {
const toolId = await downloadTool(objectName);
if (!toolId) return Promise.reject('Can not parse ToolId from the tool, installation failed.');
const oldTool = await MongoPluginModel.findOneAndUpdate(
{
toolId
Expand Down
21 changes: 12 additions & 9 deletions modules/tool/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ export function getToolType(): z.infer<typeof ToolTypeListSchema> {
}));
}

const removeFile = async (file: string) => {
try {
if (fs.existsSync(file)) {
await fs.promises.unlink(file);
}
} catch (err) {
addLog.warn(` delele File Error, ${getErrText(err)} `);
}
};

export async function refreshUploadedTools() {
addLog.info('Refreshing uploaded tools');
const existsFiles = uploadedTools.map((item) => item.toolDirName);
Expand All @@ -41,12 +51,6 @@ export async function refreshUploadedTools() {

const newFiles = tools.filter((item) => !existsFiles.includes(item.objectName.split('/').pop()!));

const removeFile = async (file: string) => {
if (fs.existsSync(file)) {
await fs.promises.unlink(file);
}
};

// merge remove and download steps into one Promise.all
await Promise.all([
...deleteFiles.map((item) =>
Expand Down Expand Up @@ -85,9 +89,8 @@ export async function downloadTool(objectName: string) {
return Promise.reject(err);
});
addLog.debug(`Downloaded tool: ${toolId}`);
return toolId;
} catch {
if (fs.existsSync(filepath)) {
await fs.promises.unlink(filepath);
}
await removeFile(filepath);
}
}
3 changes: 2 additions & 1 deletion modules/tool/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import fs from 'fs';
import { addLog } from '@/utils/log';
import { ToolTypeEnum } from './type/tool';
import { BuiltInToolBaseURL, UploadedToolBaseURL } from './utils';
import { refreshUploadedTools } from './controller';

const filterToolList = ['.DS_Store', '.git', '.github', 'node_modules', 'dist', 'scripts'];

Expand Down Expand Up @@ -131,4 +132,4 @@ export async function initUploadedTool() {
);
}

export const initTools = () => Promise.all([initBuiltInTools(), initUploadedTool()]);
export const initTools = async () => Promise.all([initBuiltInTools(), refreshUploadedTools()]);
4 changes: 2 additions & 2 deletions src/cache/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { SystemCacheKeyEnum } from './type';
import { randomUUID } from 'node:crypto';
import { initCache } from './init';
import { FASTGPT_REDIS_PREFIX, getGlobalRedisConnection } from '@/redis';
import { getGlobalRedisConnection } from '@/redis';

const cachePrefix = `${FASTGPT_REDIS_PREFIX}:VERSION_KEY:`;
const cachePrefix = `VERSION_KEY:`;

const getVersionKey = async (key: `${SystemCacheKeyEnum}`) => {
if (!global.systemCache) initCache();
Expand Down
35 changes: 33 additions & 2 deletions src/s3/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {

export class S3Service {
private client: Minio.Client;
private externalClient?: Minio.Client;
private config: S3ConfigType;

constructor(config: Partial<S3ConfigType>) {
Expand All @@ -32,6 +33,22 @@ export class S3Service {
secretKey: this.config.secretKey,
transportAgent: this.config.transportAgent
});

this.externalClient = this.config.externalBaseUrl
? (() => {
const urlObj = new URL(this.config.externalBaseUrl);
const endPoint = urlObj.hostname;
const useSSL = urlObj.protocol === 'https';
return new Minio.Client({
endPoint,
port: urlObj.port ? parseInt(urlObj.port) : useSSL ? 443 : 80,
useSSL,
accessKey: this.config.accessKey,
secretKey: this.config.secretKey,
transportAgent: this.config.transportAgent
});
})()
: undefined;
}

async initialize() {
Expand Down Expand Up @@ -290,8 +307,10 @@ export class S3Service {
const name = this.generateFileId();
const objectName = `${filepath}/${name}`;

const client = this.externalClient ?? this.client;

try {
const policy = this.client.newPostPolicy();
const policy = client.newPostPolicy();
policy.setBucket(this.config.bucket);
policy.setKey(objectName);
if (contentType) {
Expand All @@ -308,7 +327,19 @@ export class S3Service {
...metadata
});

return { ...(await this.client.presignedPostPolicy(policy)), objectName };
const res = await client.presignedPostPolicy(policy);
const postURL = (() => {
if (this.config.externalBaseUrl) {
return `${this.config.externalBaseUrl}/${this.config.bucket}`;
} else {
return res.postURL;
}
})();
return {
postURL,
formData: res.formData,
objectName
};
} catch (error) {
addLog.error('Failed to generate Upload Presigned URL', error);
return Promise.reject(`Failed to generate Upload Presigned URL: ${getErrText(error)}`);
Expand Down
3 changes: 2 additions & 1 deletion src/s3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const pluginFileS3Server = (() => {
if (!global._pluginFileS3Server) {
global._pluginFileS3Server = new S3Service({
maxFileSize: 50 * 1024 * 1024, // 默认 50MB
bucket: process.env.S3_PLUGIN_BUCKET || 'plugin_files'
bucket: process.env.S3_PLUGIN_BUCKET || 'plugin_files',
externalBaseUrl: process.env.S3_EXTERNAL_BASE_URL
});
}
return global._pluginFileS3Server;
Expand Down