Fix MinIO connection by disabling SSL and add debugging
- Change MinIO configuration to use non-SSL connection (useSSL: false) - Add test-connection endpoint to verify MinIO connectivity - Add comprehensive logging to track connection issues - Enhance error messages in list files API for better debugging
This commit is contained in:
parent
27efd8c386
commit
6c3f678554
|
|
@ -25,7 +25,7 @@ export default defineNuxtConfig({
|
||||||
minio: {
|
minio: {
|
||||||
endPoint: "s3.portnimara.com",
|
endPoint: "s3.portnimara.com",
|
||||||
port: 9000,
|
port: 9000,
|
||||||
useSSL: true,
|
useSSL: false,
|
||||||
accessKey: "279QFJV96Ja9wNB0YYmU1W3Pv4Ofeh3pxojcz0pzeC5LjRurq",
|
accessKey: "279QFJV96Ja9wNB0YYmU1W3Pv4Ofeh3pxojcz0pzeC5LjRurq",
|
||||||
secretKey: "y8ze6nmA2VHJWDsIU1eNEBq4R4WlmJWp97UE0zUR7E4zWLS6O",
|
secretKey: "y8ze6nmA2VHJWDsIU1eNEBq4R4WlmJWp97UE0zUR7E4zWLS6O",
|
||||||
bucketName: "client-portal",
|
bucketName: "client-portal",
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,17 @@ import { listFiles } from '~/server/utils/minio';
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('List files API called');
|
||||||
const query = getQuery(event);
|
const query = getQuery(event);
|
||||||
const prefix = (query.prefix as string) || '';
|
const prefix = (query.prefix as string) || '';
|
||||||
const recursive = query.recursive === 'true';
|
const recursive = query.recursive === 'true';
|
||||||
|
|
||||||
|
console.log('Listing files with prefix:', prefix, 'recursive:', recursive);
|
||||||
|
|
||||||
const files = await listFiles(prefix, recursive);
|
const files = await listFiles(prefix, recursive);
|
||||||
|
|
||||||
|
console.log('Files retrieved:', files.length);
|
||||||
|
|
||||||
// Format file list with additional metadata
|
// Format file list with additional metadata
|
||||||
const formattedFiles = (files as any[]).map(file => ({
|
const formattedFiles = (files as any[]).map(file => ({
|
||||||
...file,
|
...file,
|
||||||
|
|
@ -30,11 +35,13 @@ export default defineEventHandler(async (event) => {
|
||||||
count: formattedFiles.length,
|
count: formattedFiles.length,
|
||||||
currentPath: prefix,
|
currentPath: prefix,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error('Failed to list files:', error);
|
console.error('Failed to list files - Full error:', error);
|
||||||
|
console.error('Error message:', error.message);
|
||||||
|
console.error('Error stack:', error.stack);
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
statusMessage: 'Failed to list files',
|
statusMessage: error.message || 'Failed to list files',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
try {
|
||||||
|
const config = useRuntimeConfig().minio;
|
||||||
|
|
||||||
|
// Log configuration (without secrets)
|
||||||
|
const configInfo = {
|
||||||
|
endPoint: config.endPoint,
|
||||||
|
port: config.port,
|
||||||
|
useSSL: config.useSSL,
|
||||||
|
bucketName: config.bucketName,
|
||||||
|
hasAccessKey: !!config.accessKey,
|
||||||
|
hasSecretKey: !!config.secretKey,
|
||||||
|
accessKeyLength: config.accessKey?.length || 0,
|
||||||
|
secretKeyLength: config.secretKey?.length || 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Testing MinIO connection with config:', configInfo);
|
||||||
|
|
||||||
|
// Import MinIO client
|
||||||
|
const { Client } = await import('minio');
|
||||||
|
|
||||||
|
// Create client
|
||||||
|
const client = new Client({
|
||||||
|
endPoint: config.endPoint,
|
||||||
|
port: parseInt(config.port),
|
||||||
|
useSSL: config.useSSL,
|
||||||
|
accessKey: config.accessKey,
|
||||||
|
secretKey: config.secretKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test bucket exists
|
||||||
|
const bucketExists = await client.bucketExists(config.bucketName);
|
||||||
|
console.log(`Bucket ${config.bucketName} exists:`, bucketExists);
|
||||||
|
|
||||||
|
// If bucket doesn't exist, try to create it
|
||||||
|
if (!bucketExists) {
|
||||||
|
console.log(`Attempting to create bucket ${config.bucketName}`);
|
||||||
|
await client.makeBucket(config.bucketName, 'us-east-1');
|
||||||
|
console.log(`Bucket ${config.bucketName} created successfully`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// List buckets to verify connection
|
||||||
|
const buckets = await client.listBuckets();
|
||||||
|
console.log('Available buckets:', buckets.map(b => b.name));
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
connection: 'successful',
|
||||||
|
config: configInfo,
|
||||||
|
bucketExists,
|
||||||
|
availableBuckets: buckets.map(b => b.name),
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('MinIO connection test failed:', error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack,
|
||||||
|
code: error.code,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -5,6 +5,15 @@ import type { BucketItem } from 'minio';
|
||||||
export const getMinioClient = () => {
|
export const getMinioClient = () => {
|
||||||
const config = useRuntimeConfig().minio;
|
const config = useRuntimeConfig().minio;
|
||||||
|
|
||||||
|
console.log('MinIO Config:', {
|
||||||
|
endPoint: config.endPoint,
|
||||||
|
port: config.port,
|
||||||
|
useSSL: config.useSSL,
|
||||||
|
bucketName: config.bucketName,
|
||||||
|
hasAccessKey: !!config.accessKey,
|
||||||
|
hasSecretKey: !!config.secretKey,
|
||||||
|
});
|
||||||
|
|
||||||
return new Client({
|
return new Client({
|
||||||
endPoint: config.endPoint,
|
endPoint: config.endPoint,
|
||||||
port: config.port,
|
port: config.port,
|
||||||
|
|
@ -19,59 +28,87 @@ export const listFiles = async (prefix: string = '', recursive: boolean = false)
|
||||||
const client = getMinioClient();
|
const client = getMinioClient();
|
||||||
const bucketName = useRuntimeConfig().minio.bucketName;
|
const bucketName = useRuntimeConfig().minio.bucketName;
|
||||||
|
|
||||||
|
console.log(`Listing files from bucket: ${bucketName}, prefix: ${prefix}, recursive: ${recursive}`);
|
||||||
|
|
||||||
const files: any[] = [];
|
const files: any[] = [];
|
||||||
const folders = new Set<string>();
|
const folders = new Set<string>();
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const stream = client.listObjectsV2(bucketName, prefix, recursive);
|
try {
|
||||||
|
// First check if bucket exists
|
||||||
stream.on('data', (obj) => {
|
const bucketExists = await client.bucketExists(bucketName);
|
||||||
if (!recursive && prefix) {
|
console.log(`Bucket ${bucketName} exists:`, bucketExists);
|
||||||
// Extract folder structure when not recursive
|
|
||||||
const relativePath = obj.name.substring(prefix.length);
|
|
||||||
const firstSlash = relativePath.indexOf('/');
|
|
||||||
|
|
||||||
if (firstSlash > -1) {
|
|
||||||
// This is a folder
|
|
||||||
const folderName = relativePath.substring(0, firstSlash);
|
|
||||||
folders.add(prefix + folderName + '/');
|
|
||||||
} else if (relativePath) {
|
|
||||||
// This is a file in the current folder
|
|
||||||
files.push({
|
|
||||||
name: obj.name,
|
|
||||||
size: obj.size,
|
|
||||||
lastModified: obj.lastModified,
|
|
||||||
etag: obj.etag,
|
|
||||||
isFolder: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// When recursive or at root, include all files
|
|
||||||
if (!obj.name.endsWith('/')) {
|
|
||||||
files.push({
|
|
||||||
name: obj.name,
|
|
||||||
size: obj.size,
|
|
||||||
lastModified: obj.lastModified,
|
|
||||||
etag: obj.etag,
|
|
||||||
isFolder: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.on('error', reject);
|
|
||||||
stream.on('end', () => {
|
|
||||||
// Add folders to the result
|
|
||||||
const folderItems = Array.from(folders).map(folder => ({
|
|
||||||
name: folder,
|
|
||||||
size: 0,
|
|
||||||
lastModified: new Date(),
|
|
||||||
etag: '',
|
|
||||||
isFolder: true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
resolve([...folderItems, ...files]);
|
if (!bucketExists) {
|
||||||
});
|
console.error(`Bucket ${bucketName} does not exist`);
|
||||||
|
reject(new Error(`Bucket ${bucketName} does not exist`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stream = client.listObjectsV2(bucketName, prefix, recursive);
|
||||||
|
let objectCount = 0;
|
||||||
|
|
||||||
|
stream.on('data', (obj) => {
|
||||||
|
objectCount++;
|
||||||
|
console.log('Object found:', obj.name);
|
||||||
|
|
||||||
|
if (!recursive && prefix) {
|
||||||
|
// Extract folder structure when not recursive
|
||||||
|
const relativePath = obj.name.substring(prefix.length);
|
||||||
|
const firstSlash = relativePath.indexOf('/');
|
||||||
|
|
||||||
|
if (firstSlash > -1) {
|
||||||
|
// This is a folder
|
||||||
|
const folderName = relativePath.substring(0, firstSlash);
|
||||||
|
folders.add(prefix + folderName + '/');
|
||||||
|
} else if (relativePath) {
|
||||||
|
// This is a file in the current folder
|
||||||
|
files.push({
|
||||||
|
name: obj.name,
|
||||||
|
size: obj.size,
|
||||||
|
lastModified: obj.lastModified,
|
||||||
|
etag: obj.etag,
|
||||||
|
isFolder: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// When recursive or at root, include all files
|
||||||
|
if (!obj.name.endsWith('/')) {
|
||||||
|
files.push({
|
||||||
|
name: obj.name,
|
||||||
|
size: obj.size,
|
||||||
|
lastModified: obj.lastModified,
|
||||||
|
etag: obj.etag,
|
||||||
|
isFolder: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on('error', (error) => {
|
||||||
|
console.error('Stream error:', error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on('end', () => {
|
||||||
|
console.log(`Stream ended. Total objects processed: ${objectCount}`);
|
||||||
|
|
||||||
|
// Add folders to the result
|
||||||
|
const folderItems = Array.from(folders).map(folder => ({
|
||||||
|
name: folder,
|
||||||
|
size: 0,
|
||||||
|
lastModified: new Date(),
|
||||||
|
etag: '',
|
||||||
|
isFolder: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log(`Returning ${folderItems.length} folders and ${files.length} files`);
|
||||||
|
resolve([...folderItems, ...files]);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in listFiles:', error);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue