@hypnosis/docker-mcp-server 1.0.4 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -28
- package/dist/adapters/redis.d.ts.map +1 -1
- package/dist/adapters/redis.js +18 -6
- package/dist/adapters/redis.js.map +1 -1
- package/dist/discovery/compose-parser.d.ts +4 -0
- package/dist/discovery/compose-parser.d.ts.map +1 -1
- package/dist/discovery/compose-parser.js +25 -0
- package/dist/discovery/compose-parser.js.map +1 -1
- package/dist/discovery/project-discovery.d.ts.map +1 -1
- package/dist/discovery/project-discovery.js +24 -0
- package/dist/discovery/project-discovery.js.map +1 -1
- package/dist/discovery/remote-discovery.d.ts +99 -0
- package/dist/discovery/remote-discovery.d.ts.map +1 -0
- package/dist/discovery/remote-discovery.js +410 -0
- package/dist/discovery/remote-discovery.js.map +1 -0
- package/dist/discovery/types.d.ts +4 -0
- package/dist/discovery/types.d.ts.map +1 -1
- package/dist/index.js +85 -12
- package/dist/index.js.map +1 -1
- package/dist/managers/compose-manager.d.ts +3 -1
- package/dist/managers/compose-manager.d.ts.map +1 -1
- package/dist/managers/compose-manager.js +10 -1
- package/dist/managers/compose-manager.js.map +1 -1
- package/dist/managers/container-manager.d.ts +9 -1
- package/dist/managers/container-manager.d.ts.map +1 -1
- package/dist/managers/container-manager.js +67 -75
- package/dist/managers/container-manager.js.map +1 -1
- package/dist/tools/container-tools.d.ts +7 -1
- package/dist/tools/container-tools.d.ts.map +1 -1
- package/dist/tools/container-tools.js +156 -18
- package/dist/tools/container-tools.js.map +1 -1
- package/dist/tools/database-tools.d.ts.map +1 -1
- package/dist/tools/database-tools.js +36 -4
- package/dist/tools/database-tools.js.map +1 -1
- package/dist/tools/discovery-tools.d.ts +29 -0
- package/dist/tools/discovery-tools.d.ts.map +1 -0
- package/dist/tools/discovery-tools.js +173 -0
- package/dist/tools/discovery-tools.js.map +1 -0
- package/dist/tools/env-tools.d.ts +5 -0
- package/dist/tools/env-tools.d.ts.map +1 -1
- package/dist/tools/env-tools.js +158 -15
- package/dist/tools/env-tools.js.map +1 -1
- package/dist/tools/executor-tool.d.ts +5 -0
- package/dist/tools/executor-tool.d.ts.map +1 -1
- package/dist/tools/executor-tool.js +60 -5
- package/dist/tools/executor-tool.js.map +1 -1
- package/dist/tools/mcp-health-tool.d.ts +11 -0
- package/dist/tools/mcp-health-tool.d.ts.map +1 -1
- package/dist/tools/mcp-health-tool.js +25 -4
- package/dist/tools/mcp-health-tool.js.map +1 -1
- package/dist/tools/profile-tool.d.ts +46 -0
- package/dist/tools/profile-tool.d.ts.map +1 -0
- package/dist/tools/profile-tool.js +91 -0
- package/dist/tools/profile-tool.js.map +1 -0
- package/dist/utils/compose-exec.d.ts +28 -3
- package/dist/utils/compose-exec.d.ts.map +1 -1
- package/dist/utils/compose-exec.js +100 -26
- package/dist/utils/compose-exec.js.map +1 -1
- package/dist/utils/docker-client.d.ts +73 -8
- package/dist/utils/docker-client.d.ts.map +1 -1
- package/dist/utils/docker-client.js +492 -16
- package/dist/utils/docker-client.js.map +1 -1
- package/dist/utils/profiles-file.d.ts +57 -0
- package/dist/utils/profiles-file.d.ts.map +1 -0
- package/dist/utils/profiles-file.js +167 -0
- package/dist/utils/profiles-file.js.map +1 -0
- package/dist/utils/retry.d.ts +49 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +120 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/ssh-config.d.ts +104 -0
- package/dist/utils/ssh-config.d.ts.map +1 -0
- package/dist/utils/ssh-config.js +346 -0
- package/dist/utils/ssh-config.js.map +1 -0
- package/dist/utils/ssh-exec.d.ts +59 -0
- package/dist/utils/ssh-exec.d.ts.map +1 -0
- package/dist/utils/ssh-exec.js +156 -0
- package/dist/utils/ssh-exec.js.map +1 -0
- package/package.json +21 -3
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profiles File Loader
|
|
3
|
+
* Load SSH profiles from JSON configuration file
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, existsSync } from 'fs';
|
|
6
|
+
import { resolve } from 'path';
|
|
7
|
+
import { logger } from './logger.js';
|
|
8
|
+
/**
|
|
9
|
+
* Load profiles from JSON file
|
|
10
|
+
*
|
|
11
|
+
* @param filePath - Path to profiles JSON file
|
|
12
|
+
* @returns Profiles configuration and errors
|
|
13
|
+
*/
|
|
14
|
+
export function loadProfilesFile(filePath) {
|
|
15
|
+
const errors = [];
|
|
16
|
+
try {
|
|
17
|
+
// Resolve path (support ~ for home directory)
|
|
18
|
+
const resolvedPath = resolveFilePath(filePath);
|
|
19
|
+
// Check if file exists
|
|
20
|
+
if (!existsSync(resolvedPath)) {
|
|
21
|
+
errors.push(`Profiles file not found: ${resolvedPath}`);
|
|
22
|
+
return { config: null, errors };
|
|
23
|
+
}
|
|
24
|
+
// Read and parse JSON
|
|
25
|
+
const fileContent = readFileSync(resolvedPath, 'utf-8');
|
|
26
|
+
const parsed = JSON.parse(fileContent);
|
|
27
|
+
// Validate structure
|
|
28
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
29
|
+
errors.push('Profiles file must contain a JSON object');
|
|
30
|
+
return { config: null, errors };
|
|
31
|
+
}
|
|
32
|
+
if (!parsed.profiles || typeof parsed.profiles !== 'object') {
|
|
33
|
+
errors.push('Profiles file must have a "profiles" object');
|
|
34
|
+
return { config: null, errors };
|
|
35
|
+
}
|
|
36
|
+
// Validate each profile
|
|
37
|
+
const profiles = {};
|
|
38
|
+
for (const [name, data] of Object.entries(parsed.profiles)) {
|
|
39
|
+
if (typeof data !== 'object' || data === null) {
|
|
40
|
+
errors.push(`Profile "${name}" must be an object`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const profile = data;
|
|
44
|
+
// Check if this is a local mode profile
|
|
45
|
+
if (profile.mode === 'local') {
|
|
46
|
+
// For local mode, only mode is required
|
|
47
|
+
const profileData = {
|
|
48
|
+
mode: 'local',
|
|
49
|
+
};
|
|
50
|
+
// projectsPath is optional even for local
|
|
51
|
+
if (profile.projectsPath && typeof profile.projectsPath === 'string') {
|
|
52
|
+
profileData.projectsPath = profile.projectsPath.trim();
|
|
53
|
+
}
|
|
54
|
+
profiles[name] = profileData;
|
|
55
|
+
logger.debug(`Profile "${name}" configured for LOCAL mode`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// For remote mode (mode === 'remote' or mode not specified), validate required fields
|
|
59
|
+
if (!profile.host || typeof profile.host !== 'string') {
|
|
60
|
+
errors.push(`Profile "${name}" must have a "host" string (or set mode: "local" for local Docker)`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (!profile.username || typeof profile.username !== 'string') {
|
|
64
|
+
errors.push(`Profile "${name}" must have a "username" string (or set mode: "local" for local Docker)`);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
// Build remote profile
|
|
68
|
+
const profileData = {
|
|
69
|
+
mode: profile.mode === 'remote' ? 'remote' : undefined, // Explicitly set if specified
|
|
70
|
+
host: profile.host.trim(),
|
|
71
|
+
username: profile.username.trim(),
|
|
72
|
+
};
|
|
73
|
+
// Optional fields
|
|
74
|
+
if (profile.port !== undefined) {
|
|
75
|
+
const port = typeof profile.port === 'number' ? profile.port : parseInt(String(profile.port), 10);
|
|
76
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
77
|
+
errors.push(`Profile "${name}" has invalid port: ${profile.port}`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
profileData.port = port;
|
|
81
|
+
}
|
|
82
|
+
if (profile.privateKeyPath && typeof profile.privateKeyPath === 'string') {
|
|
83
|
+
profileData.privateKeyPath = profile.privateKeyPath.trim();
|
|
84
|
+
}
|
|
85
|
+
if (profile.passphrase && typeof profile.passphrase === 'string') {
|
|
86
|
+
profileData.passphrase = profile.passphrase;
|
|
87
|
+
}
|
|
88
|
+
if (profile.password && typeof profile.password === 'string') {
|
|
89
|
+
profileData.password = profile.password;
|
|
90
|
+
}
|
|
91
|
+
if (profile.projectsPath && typeof profile.projectsPath === 'string') {
|
|
92
|
+
profileData.projectsPath = profile.projectsPath.trim();
|
|
93
|
+
}
|
|
94
|
+
profiles[name] = profileData;
|
|
95
|
+
}
|
|
96
|
+
if (Object.keys(profiles).length === 0) {
|
|
97
|
+
errors.push('No valid profiles found in file');
|
|
98
|
+
return { config: null, errors };
|
|
99
|
+
}
|
|
100
|
+
// Build config
|
|
101
|
+
const config = {
|
|
102
|
+
profiles,
|
|
103
|
+
};
|
|
104
|
+
// Set default profile if specified
|
|
105
|
+
if (parsed.default && typeof parsed.default === 'string') {
|
|
106
|
+
if (profiles[parsed.default]) {
|
|
107
|
+
config.default = parsed.default;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
errors.push(`Default profile "${parsed.default}" not found in profiles`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (errors.length > 0) {
|
|
114
|
+
return { config: null, errors };
|
|
115
|
+
}
|
|
116
|
+
logger.info(`Loaded ${Object.keys(profiles).length} profiles from ${resolvedPath}`);
|
|
117
|
+
if (config.default) {
|
|
118
|
+
logger.info(`Default profile: ${config.default}`);
|
|
119
|
+
}
|
|
120
|
+
return { config, errors: [] };
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.name === 'SyntaxError') {
|
|
124
|
+
errors.push(`Invalid JSON in profiles file: ${error.message}`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
errors.push(`Failed to load profiles file: ${error.message}`);
|
|
128
|
+
}
|
|
129
|
+
return { config: null, errors };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Convert profile data to SSHConfig
|
|
134
|
+
* @throws Error with code 'LOCAL_MODE' if profile is configured for local Docker
|
|
135
|
+
*/
|
|
136
|
+
export function profileDataToSSHConfig(data) {
|
|
137
|
+
// Check if this is a local mode profile
|
|
138
|
+
if (data.mode === 'local') {
|
|
139
|
+
const error = new Error('Profile is configured for LOCAL mode');
|
|
140
|
+
error.code = 'LOCAL_MODE';
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
// For remote profiles, host and username are required
|
|
144
|
+
if (!data.host || !data.username) {
|
|
145
|
+
throw new Error('Profile must have host and username for remote mode');
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
host: data.host,
|
|
149
|
+
username: data.username,
|
|
150
|
+
port: data.port || 22,
|
|
151
|
+
privateKeyPath: data.privateKeyPath,
|
|
152
|
+
passphrase: data.passphrase,
|
|
153
|
+
password: data.password,
|
|
154
|
+
projectsPath: data.projectsPath,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Resolve file path with ~ expansion
|
|
159
|
+
*/
|
|
160
|
+
function resolveFilePath(filePath) {
|
|
161
|
+
if (filePath.startsWith('~')) {
|
|
162
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
163
|
+
return filePath.replace('~', home);
|
|
164
|
+
}
|
|
165
|
+
return resolve(filePath);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=profiles-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles-file.js","sourceRoot":"","sources":["../../src/utils/profiles-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry & Timeout Utility
|
|
3
|
+
* Утилита для повторных попыток с экспоненциальным backoff и timeout
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Опции для retry функции
|
|
7
|
+
*/
|
|
8
|
+
export interface RetryOptions {
|
|
9
|
+
/** Максимальное количество попыток (по умолчанию 3) */
|
|
10
|
+
maxAttempts?: number;
|
|
11
|
+
/** Таймаут на операцию в миллисекундах (по умолчанию 30000 = 30 секунд) */
|
|
12
|
+
timeout?: number;
|
|
13
|
+
/** Начальная задержка перед повторной попыткой в миллисекундах (по умолчанию 1000 = 1 секунда) */
|
|
14
|
+
initialDelay?: number;
|
|
15
|
+
/** Множитель для экспоненциального backoff (по умолчанию 2) */
|
|
16
|
+
backoffMultiplier?: number;
|
|
17
|
+
/** Функция для проверки, стоит ли повторять попытку для данной ошибки */
|
|
18
|
+
shouldRetry?: (error: any) => boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Ошибка таймаута
|
|
22
|
+
*/
|
|
23
|
+
export declare class TimeoutError extends Error {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Ошибка исчерпания попыток
|
|
28
|
+
*/
|
|
29
|
+
export declare class RetryExhaustedError extends Error {
|
|
30
|
+
readonly attempts: number;
|
|
31
|
+
readonly lastError: any;
|
|
32
|
+
constructor(attempts: number, lastError: any);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Выполнить функцию с повторными попытками и таймаутом
|
|
36
|
+
*
|
|
37
|
+
* @param fn - Асинхронная функция для выполнения
|
|
38
|
+
* @param options - Опции retry
|
|
39
|
+
* @returns Результат выполнения функции
|
|
40
|
+
* @throws TimeoutError - если операция превысила timeout
|
|
41
|
+
* @throws RetryExhaustedError - если исчерпаны все попытки
|
|
42
|
+
*/
|
|
43
|
+
export declare function retryWithTimeout<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
44
|
+
/**
|
|
45
|
+
* Создать функцию shouldRetry для сетевых ошибок
|
|
46
|
+
* Повторяет попытку для сетевых ошибок и таймаутов, но не для ошибок валидации
|
|
47
|
+
*/
|
|
48
|
+
export declare function createNetworkRetryPredicate(): (error: any) => boolean;
|
|
49
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC;CACvC;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,GAAE,MAA8B;CAIpD;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,SAAS,EAAE,GAAG,CAAC;gBAEnB,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;CAM7C;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CA+DZ;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CA6BrE"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry & Timeout Utility
|
|
3
|
+
* Утилита для повторных попыток с экспоненциальным backoff и timeout
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from './logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Ошибка таймаута
|
|
8
|
+
*/
|
|
9
|
+
export class TimeoutError extends Error {
|
|
10
|
+
constructor(message = 'Operation timed out') {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'TimeoutError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Ошибка исчерпания попыток
|
|
17
|
+
*/
|
|
18
|
+
export class RetryExhaustedError extends Error {
|
|
19
|
+
attempts;
|
|
20
|
+
lastError;
|
|
21
|
+
constructor(attempts, lastError) {
|
|
22
|
+
super(`Operation failed after ${attempts} attempts: ${lastError.message}`);
|
|
23
|
+
this.name = 'RetryExhaustedError';
|
|
24
|
+
this.attempts = attempts;
|
|
25
|
+
this.lastError = lastError;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Выполнить функцию с повторными попытками и таймаутом
|
|
30
|
+
*
|
|
31
|
+
* @param fn - Асинхронная функция для выполнения
|
|
32
|
+
* @param options - Опции retry
|
|
33
|
+
* @returns Результат выполнения функции
|
|
34
|
+
* @throws TimeoutError - если операция превысила timeout
|
|
35
|
+
* @throws RetryExhaustedError - если исчерпаны все попытки
|
|
36
|
+
*/
|
|
37
|
+
export async function retryWithTimeout(fn, options = {}) {
|
|
38
|
+
const { maxAttempts = 3, timeout = 30000, initialDelay = 1000, backoffMultiplier = 2, shouldRetry = () => true, // По умолчанию повторяем для любых ошибок
|
|
39
|
+
} = options;
|
|
40
|
+
let lastError;
|
|
41
|
+
let delay = initialDelay;
|
|
42
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
43
|
+
try {
|
|
44
|
+
// Создаем Promise с таймаутом
|
|
45
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
reject(new TimeoutError(`Operation timed out after ${timeout}ms`));
|
|
48
|
+
}, timeout);
|
|
49
|
+
});
|
|
50
|
+
// Выполняем функцию с таймаутом
|
|
51
|
+
const result = await Promise.race([fn(), timeoutPromise]);
|
|
52
|
+
// Если успешно выполнено с первой попытки - не логируем
|
|
53
|
+
if (attempt > 1) {
|
|
54
|
+
logger.info(`Operation succeeded on attempt ${attempt}/${maxAttempts}`);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
lastError = error;
|
|
60
|
+
// Если это TimeoutError - не повторяем
|
|
61
|
+
if (error instanceof TimeoutError) {
|
|
62
|
+
logger.error(`Operation timed out on attempt ${attempt}/${maxAttempts}`);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
// Проверяем, стоит ли повторять попытку
|
|
66
|
+
if (!shouldRetry(error)) {
|
|
67
|
+
logger.error(`Operation failed on attempt ${attempt}/${maxAttempts}, not retrying: ${error.message}`);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
// Если это последняя попытка - выбрасываем ошибку
|
|
71
|
+
if (attempt >= maxAttempts) {
|
|
72
|
+
logger.error(`Operation failed after ${maxAttempts} attempts: ${error.message}`);
|
|
73
|
+
throw new RetryExhaustedError(maxAttempts, lastError);
|
|
74
|
+
}
|
|
75
|
+
// Логируем попытку и ждем перед следующей
|
|
76
|
+
logger.warn(`Operation failed on attempt ${attempt}/${maxAttempts}: ${error.message}. Retrying in ${delay}ms...`);
|
|
77
|
+
await sleep(delay);
|
|
78
|
+
// Увеличиваем задержку для следующей попытки (экспоненциальный backoff)
|
|
79
|
+
delay *= backoffMultiplier;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Этот код не должен выполняться, но на всякий случай
|
|
83
|
+
throw new RetryExhaustedError(maxAttempts, lastError);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Создать функцию shouldRetry для сетевых ошибок
|
|
87
|
+
* Повторяет попытку для сетевых ошибок и таймаутов, но не для ошибок валидации
|
|
88
|
+
*/
|
|
89
|
+
export function createNetworkRetryPredicate() {
|
|
90
|
+
return (error) => {
|
|
91
|
+
// Повторяем для сетевых ошибок
|
|
92
|
+
if (error.code === 'ECONNREFUSED' ||
|
|
93
|
+
error.code === 'ETIMEDOUT' ||
|
|
94
|
+
error.code === 'ENOTFOUND' ||
|
|
95
|
+
error.code === 'EAI_AGAIN' ||
|
|
96
|
+
error.code === 'ECONNRESET') {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// Повторяем для ошибок с сообщениями о таймауте
|
|
100
|
+
if (error.message && (error.message.includes('timeout') ||
|
|
101
|
+
error.message.includes('timed out') ||
|
|
102
|
+
error.message.includes('connection') ||
|
|
103
|
+
error.message.includes('network'))) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
// Не повторяем для ошибок валидации или авторизации
|
|
107
|
+
if (error.statusCode === 400 || error.statusCode === 401 || error.statusCode === 403) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
// По умолчанию повторяем
|
|
111
|
+
return true;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Утилита для задержки
|
|
116
|
+
*/
|
|
117
|
+
function sleep(ms) {
|
|
118
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Configuration Module
|
|
3
|
+
* SSH configuration management for remote Docker
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* SSH configuration for connecting to remote Docker server
|
|
7
|
+
*/
|
|
8
|
+
export interface SSHConfig {
|
|
9
|
+
/** Server address (IP or domain name) */
|
|
10
|
+
host: string;
|
|
11
|
+
/** SSH port (default: 22) */
|
|
12
|
+
port?: number;
|
|
13
|
+
/** Username for SSH connection */
|
|
14
|
+
username: string;
|
|
15
|
+
/** Path to private SSH key */
|
|
16
|
+
privateKeyPath?: string;
|
|
17
|
+
/** Passphrase for encrypted SSH key */
|
|
18
|
+
passphrase?: string;
|
|
19
|
+
/** Password for authentication (not recommended for production) */
|
|
20
|
+
password?: string;
|
|
21
|
+
/** Base path for Docker projects on remote server (e.g., "/var/www") */
|
|
22
|
+
projectsPath?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* SSH profile with name and configuration
|
|
26
|
+
* Allows working with multiple servers
|
|
27
|
+
*/
|
|
28
|
+
export interface SSHProfile {
|
|
29
|
+
/** Profile name (e.g., 'production', 'staging') */
|
|
30
|
+
name: string;
|
|
31
|
+
/** SSH configuration */
|
|
32
|
+
config: SSHConfig;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* SSH configuration loading result
|
|
36
|
+
*/
|
|
37
|
+
export interface SSHConfigResult {
|
|
38
|
+
/** SSH configuration or null if not found */
|
|
39
|
+
config: SSHConfig | null;
|
|
40
|
+
/** Validation errors (if any) */
|
|
41
|
+
errors: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* SSH profiles loading result
|
|
45
|
+
*/
|
|
46
|
+
export interface SSHProfilesResult {
|
|
47
|
+
/** Profiles or empty object if not found */
|
|
48
|
+
profiles: Record<string, SSHConfig>;
|
|
49
|
+
/** Validation errors (if any) */
|
|
50
|
+
errors: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Валидация SSH конфигурации
|
|
54
|
+
* @param config - SSH конфигурация для проверки
|
|
55
|
+
* @returns Массив ошибок (пустой, если валидация прошла успешно)
|
|
56
|
+
*/
|
|
57
|
+
export declare function validateSSHConfig(config: Partial<SSHConfig>): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Load SSH configuration from environment variables or profiles file
|
|
60
|
+
*
|
|
61
|
+
* Priority order:
|
|
62
|
+
* 1. DOCKER_MCP_PROFILES_FILE - Load from JSON file
|
|
63
|
+
* 2. DOCKER_SSH_PROFILE + DOCKER_SSH_PROFILES - Load from env JSON
|
|
64
|
+
* 3. DOCKER_SSH_HOST + DOCKER_SSH_USER - Simple single server config
|
|
65
|
+
*
|
|
66
|
+
* @param env - Environment variables object (defaults to process.env)
|
|
67
|
+
* @param profileName - Optional profile name to load (overrides DOCKER_SSH_PROFILE)
|
|
68
|
+
* @returns SSH configuration result with config and errors
|
|
69
|
+
*/
|
|
70
|
+
export declare function loadSSHConfig(env?: Record<string, string | undefined>, profileName?: string): SSHConfigResult;
|
|
71
|
+
/**
|
|
72
|
+
* Загрузить SSH профили из environment variables
|
|
73
|
+
*
|
|
74
|
+
* Формат DOCKER_SSH_PROFILES: JSON объект
|
|
75
|
+
* {
|
|
76
|
+
* "profile1": {
|
|
77
|
+
* "host": "server1.com",
|
|
78
|
+
* "username": "user1",
|
|
79
|
+
* "port": 22,
|
|
80
|
+
* "privateKeyPath": "/path/to/key1"
|
|
81
|
+
* },
|
|
82
|
+
* "profile2": {
|
|
83
|
+
* "host": "server2.com",
|
|
84
|
+
* "username": "user2"
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
*
|
|
88
|
+
* @param env - Объект с environment variables (по умолчанию process.env)
|
|
89
|
+
* @returns Результат загрузки с профилями и ошибками
|
|
90
|
+
*/
|
|
91
|
+
export declare function loadSSHProfiles(env?: Record<string, string | undefined>): SSHProfilesResult;
|
|
92
|
+
/**
|
|
93
|
+
* Get active SSH profile name
|
|
94
|
+
* @param env - Environment variables object
|
|
95
|
+
* @returns Active profile name or null
|
|
96
|
+
*/
|
|
97
|
+
export declare function getActiveSSHProfile(env?: Record<string, string | undefined>): string | null;
|
|
98
|
+
/**
|
|
99
|
+
* Проверить существование SSH ключа по пути
|
|
100
|
+
* @param keyPath - Путь к SSH ключу
|
|
101
|
+
* @returns true, если ключ существует
|
|
102
|
+
*/
|
|
103
|
+
export declare function checkSSHKeyExists(keyPath: string): boolean;
|
|
104
|
+
//# sourceMappingURL=ssh-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-config.d.ts","sourceRoot":"","sources":["../../src/utils/ssh-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,iCAAiC;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,iCAAiC;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,CAuCtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,WAAW,CAAC,EAAE,MAAM,GACnB,eAAe,CAgHjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,iBAAiB,CA0FxG;AA6ED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,GAAG,IAAI,CAExG;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAW1D"}
|