پرش به مطلب اصلی

اجرای دستور درون کانتینر

یک دستور جدید را درون کانتینر در حال اجرا اجرا می‌کند.


🧩 دستور کلی

async execInContainer(containerId, command, options = {})

شرح عملکرد

این متد یک دستور را داخل کانتینر اجرا می‌کند. شامل:

  • تأیید کانتینر درحال اجرا است
  • اجرای دستور به صورت interactive یا detach
  • انتخاب کاربر اجرای دستور
  • تنظیم دایرکتوری کاری

مهم: کانتینر باید در حال اجرا باشد. دستور فقط درون کانتینر فعال قابل اجرا است.


ورودی‌ها

پارامترنوعاجباریتوضیح
containerIdStringبلهشناسه یا نام کانتینر
commandArrayبلهدستور و آرگومان‌ها (مثل: ['ls', '-la'])
optionsObjectبلهگزینه‌های اجرا
options.interactiveBooleanخیرباز نگه داشتن STDIN
options.ttyBooleanخیرتخصیص pseudo-TTY
options.detachBooleanخیراجرای پس‌زمینه (پیش‌فرض: true)
options.userStringخیرکاربر اجرای دستور
options.cwdStringخیردایرکتوری کاری (working directory)
options.consoleSocketStringخیرمسیر socket برای TTY
options.apparmorStringخیرپروفایل AppArmor
options.debugBooleanخیرفعال کردن حالت debug

خروجی

نوع: String (خروجی دستور)

نمونه خروجی:

total 1
drwxr-xr-x 1 root root 4096 Jan 1 00:00 .
drwxr-xr-x 1 root root 4096 Jan 1 00:00 ..
drwxr-xr-x 2 root root 4096 Jan 1 00:00 bin
drwxr-xr-x 2 root root 4096 Jan 1 00:00 dev
drwxr-xr-x 2 root root 4096 Jan 1 00:00 etc

استثناها (Errors)

OptionConflict (422)

پیام: "Failed to validate exec options." یا "Invalid DTO options."

زمان رخ دادن: گزینه‌های ورودی نامعتبر یا دستور خالی

جزئیات:

{
"type": "VALIDATION_ERROR",
"statusCode": 422,
"error": "Invalid schema or invalid dto"
}

راهنمای حل:

  • دستور باید آرایه‌ای از رشته‌ها باشد
  • گزینه‌های boolean را بررسی کنید
  • دستور خالی نباشد

ResolveContainerName (500)

پیام: "Database error occurred while resolving container name or ID."

زمان رخ دادن: خطای دیتابیس در تطابق شناسه/نام کانتینر

جزئیات:

{
"type": "DB_ERROR",
"statusCode": 500,
"input": "container-id",
"error": "Database connection lost"
}

راهنمای حل:

  • اتصال دیتابیس را بررسی کنید
  • لاگ‌های دیتابیس را مطالعه کنید
  • دیتابیس را راه‌اندازی کنید

ContainerNotFound (404)

پیام: "Container not found."

زمان رخ دادن: کانتینری با شناسه/نام درخواستی یافت نشود

جزئیات:

{
"type": "NOT_FOUND",
"statusCode": 404,
"containerId": "invalid-id"
}

راهنمای حل:

  • شناسه کانتینر را بررسی کنید
  • listContainers() استفاده کنید تا تمام کانتینرها را ببینید
  • نام یا ID صحیح را وارد کنید

FetchContainerState (500)

پیام: "Database error occurred while fetching container state."

زمان رخ دادن: خطا در خواندن اطلاعات کانتینر

جزئیات:

{
"type": "DB_ERROR",
"statusCode": 500,
"containerId": "abc123def456",
"error": "Query failed"
}

راهنمای حل:

  • دیتابیس را بررسی کنید
  • اتصال را تأیید کنید

NotRunning (400)

پیام: "Container is not running."

زمان رخ دادن: کانتینر در حال اجرا نیست

جزئیات:

{
"type": "INVALID_STATE",
"statusCode": 400,
"containerId": "abc123def456",
"state": "stopped"
}

راهنمای حل:

  • startContainer() استفاده کنید تا کانتینر را شروع کنید
  • وضعیت کانتینر را بررسی کنید
  • inspectContainer() برای جزئیات بیشتر

ExecInFailure (500)

پیام: "Failed to execute command in container."

زمان رخ دادن: خطا در اجرای دستور

جزئیات:

{
"type": "CONTAINER_SERVICE_ERROR",
"statusCode": 500,
"containerId": "abc123def456",
"error": "Command execution failed"
}

راهنمای حل:

  • دستور را بررسی کنید (آیا معتبر است؟)
  • اجازه‌های فایل را تأیید کنید
  • لاگ‌های کانتینر را مطالعه کنید

مثال‌های استفاده

مثال 1: اجرای دستور ساده

const K3Core = require('k3-core');

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'my-container',
['echo', 'Hello from container'],
{}
);
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 2: اجرای دستور ls با پارامتر

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'web-server',
['ls', '-la', '/var/www'],
{ detach: false }
);
console.log('Directory listing:');
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 3: اجرای دستور با TTY تفاعلی

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'app-container',
['bash'],
{
interactive: true,
tty: true,
detach: false
}
);
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 4: اجرای دستور به عنوان کاربر خاص

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'app-container',
['whoami'],
{ user: 'www-data' }
);
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 5: اجرای دستور در دایرکتوری خاص

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'project-container',
['npm', 'test'],
{ cwd: '/app' }
);
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 6: اجرای دستور پس‌زمینه

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'background-container',
['python', 'long_running_task.py'],
{ detach: true }
);
console.log('Background process started');
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 7: اجرای دستور با debug mode

(async () => {
const k3 = new K3Core();

try {
const result = await k3.containerCore.execInContainer(
'debug-container',
['ps', 'aux'],
{ debug: true }
);
console.log('Debug output:');
} catch (error) {
console.log(error.createFullMessage());
}
})();

مثال 8: اجرای دستور پیچیده با بررسی قبلی

(async () => {
const k3 = new K3Core();
const containerId = 'target-container';

try {
// Step 1: بررسی وضعیت کانتینر
const inspect = await k3.containerCore.inspectContainer(containerId);

if (!inspect) {
console.log('Container not found');
return;
}

if (!inspect.state?.running) {
console.log('Container is not running');
console.log('Starting container...');
await k3.containerCore.startContainer(containerId, {});
await new Promise(resolve => setTimeout(resolve, 2000));
}

console.log(`Executing command in: ${inspect.name}`);

// Step 2: اجرای دستور
const result = await k3.containerCore.execInContainer(
containerId,
['cat', '/etc/hostname'],
{ detach: false }
);


} catch (error) {
console.log(error.createFullMessage());
}
})();

الگوهای خطا و راهنمای حل

الگو 1: کانتینر درحال اجرا نیست

خطا: NotRunning (400)

راهنمای حل:

try {
await k3.containerCore.execInContainer('stopped-container', ['ls'], {});
} catch (error) {
if (error.type === 'INVALID_STATE') {
console.log('Container is not running, starting it...');

// شروع کانتینر
await k3.containerCore.startContainer('stopped-container', {});

// انتظار برای startup
await new Promise(resolve => setTimeout(resolve, 2000));

// تلاش مجدد
const result = await k3.containerCore.execInContainer('stopped-container', ['ls'], {});
} else {
console.log(error.createFullMessage());
}
}

الگو 2: کانتینر یافت نشد

خطا: ContainerNotFound (404)

راهنمای حل:

try {
await k3.containerCore.execInContainer('invalid-container', ['ls'], {});
} catch (error) {
if (error.type === 'NOT_FOUND') {
const allContainers = await k3.containerCore.listContainers({ all: true });
console.log('Available containers:', allContainers.map(c => c.name));

const container = allContainers.find(c => c.name.includes('target'));
if (container && container.state?.running) {
await k3.containerCore.execInContainer(container.id, ['ls'], {});
}
} else {
console.log(error.createFullMessage());
}
}

الگو 3: اجرای دستور با خطا

خطا: ExecInFailure (500)

راهنمای حل:

try {
const result = await k3.containerCore.execInContainer(
'app-container',
['python', 'script.py'],
{ detach: false }
);
} catch (error) {
if (error.type === 'CONTAINER_SERVICE_ERROR') {
console.log('Command execution failed');
console.log('Possible issues:');
console.log('- Script file not found');
console.log('- Permission denied');
console.log('- Python not installed in container');

// بررسی فایل
try {
const checkResult = await k3.containerCore.execInContainer(
'app-container',
['ls', '-la', 'script.py'],
{}
);
console.log('File check:', checkResult);
} catch (checkError) {
console.log('File does not exist');
}
} else {
console.log(error.createFullMessage());
}
}

الگو 54: اجرای دستور با بررسی خروجی

راهنمای حل:

const execWithValidation = async (containerId, command, expectedPattern) => {
try {
const result = await k3.containerCore.execInContainer(
containerId,
command,
{ detach: false }
);

return result;

} catch (error) {
console.log('Command execution failed');
throw error;
}
};

// استفاده
try {
const output = await execWithValidation(
'web-server',
['curl', 'localhost:8080/health'],
'OK'
);
console.log('Health check passed');
} catch (error) {
console.log('Health check failed:', error.message);
}

نکات عملی

  1. Command Format:

    • باید آرایه‌ای از رشته‌ها باشد
    • مثال: ['echo', 'hello']
    • مثال: ['npm', 'test', '--verbose']
  2. Interactive vs Detach:

    • interactive: true, tty: true - برای interactive shells
    • detach: true - برای background processes
    • detach: false - برای دریافت خروجی
  3. User Parameter:

    • مثال: user: 'www-data'
    • مثال: user: 'root'
    • باید کاربر در کانتینر موجود باشد
  4. Working Directory:

    • مثال: cwd: '/app'
    • مثال: cwd: '/home/user'
    • باید دایرکتوری در کانتینر موجود باشد
  5. Container State:

    • کانتینر باید در حال اجرا باشد
    • اگر متوقف است، ابتدا شروع کنید
    • وضعیت را با inspectContainer() بررسی کنید
  6. TTY and Pseudo-terminal:

    • tty: true برای interactive shells
    • tty: false برای non-interactive commands
    • interactive: true STDIN را باز نگه می‌دارد
  7. Output Handling:

    • خروجی دستور بازگشت داده می‌شود
    • اگر detach: true، فقط status بازگشت داده می‌شود
    • برای capturing output از detach: false استفاده کنید
  8. Error Handling:

    • دستور نامعتبر خطای ExecInFailure می‌دهد
    • فایل نیافته‌شده خطای 127 می‌دهد
    • Permission denied خطای 13 می‌دهد

دنباله عملیات

  1. Validate options and command
  2. Resolve container name/ID
  3. Fetch container hash ID
  4. Check container is running
  5. Build exec DTO options
  6. Execute command via container manager
  7. Return output
  8. Log operation

مرجع سریع

وضعیتکدتوضیح
موفق200دستور اجرا شد
گزینه نامعتبر422OptionConflict
یافت نشد404ContainerNotFound
درحال اجرا نیست400NotRunning
خطای دیتابیس500ResolveContainerName
خطای اجرا500ExecInFailure

نسخه: 1.3
تاریخ آپدیت: 9 آذرماه ۱۴۰۴
تیم توسعه: K3 Development Team