دانلود ایمیج
ایمیج را دور دانلود کرده و در رجیستری محلی ذخیره میکند.
🧩 دستور کلی
async pullAnImage(imageName, imageTag = "latest", optionsObject = {})
شرح عملکرد
این متد ایمیج را دور (مانند Docker Hub) دانلود میکند و در محل محلی ذخیره میکند. شامل:
- اعتبارسنجی نام ایمیج و تگ
- بررسی وجود ایمیج (جلوگیری از دانلود تکراری)
- ایجاد دایرکتوری ایمیج اگر نیاز باشد
- بررسی اطلاعات ایمیج از رجیستری
- بررسی فضای دیسک دستیاب
- دانلود ایمیج با استفاده از skopeo
- یافتن blobهای ایمیج
- ایجاد رکوردهای blob در پایگاه داده
- محاسبه اندازه ایمیج
- دریافت تاریخچه ایمیج
- ایجاد رکورد ایمیج در پایگاه داده
- logging عملیات
مهم: Pull عملیات زمانبر است و نیاز به اتصال شبکه دارد. فضای دیسک کافی باید موجود باشد (حداقل 2.5 برابر اندازه ایمیج).
ورودیها
| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
imageName | String | بله | نام ایمیج (مثلاً alpine, nginx, myrepo/myimage) |
imageTag | String | خیر | نام تگ (پیشفرض: latest) |
optionsObject | Object | خیر | گزینههای اضافی (مثل proxy, credentials) |
خروجی
نوع: String
پیام موفقیت:
alpine:latest has pulled successfully
یا:
nginx:1.25 has pulled successfully
استثناها (Errors)
InvalidImageNameOrTag (422)
پیام: "Invalid image name or tag format."
زمان رخ دادن: نام ایمیج یا تگ نامعتبر باشد
جزئیات:
{
"type": "VALIDATION_ERROR",
"statusCode": 422,
"imageName": "invalid@image",
"imageTag": "latest",
"error": "Image name contains invalid characters"
}
راهنمای حل:
- نام ایمیج: فقط حروف، اعداد، '-', '_', '/' مجاز
- تگ: فقط حروف، اعداد، '.', '-' مجاز
- فرمت صحیح:
imageName:tagیاrepo/imageName:tag
ImageAlreadyExists (409)
پیام: "Image already exists in local registry."
زمان رخ دادن: ایمیج با همین نام و تگ قبلاً دانلود شده است
جزئیات:
{
"type": "INVALID_STATE_ERROR",
"statusCode": 409,
"imageName": "alpine",
"imageTag": "latest",
"error": "Image already exists"
}
راهنمای حل:
- ایمیج قبلاً دانلود شده است
- برای بروزرسانی، ابتدا ایمیج قدیم را حذف کنید
- یا تگ متفاوتی استفاده کنید
FetchImageState (500)
پیام: "Failed to check image state in database."
زمان رخ دادن: خطا در بررسی وجود ایمیج در DB
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"imageName": "nginx",
"imageTag": "latest",
"error": "Database query failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را restart کنید
- لاگهای DB را بررسی کنید
CreateImageDirectoryFailure (500)
پیام: "Failed to create image directory."
زمان رخ دادن: خطا در ایجاد دایرکتوری ایمیج
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "ubuntu",
"error": "Directory creation failed"
}
راهنمای حل:
- اجازههای فایل سیستم را بررسی کنید
- مسیر
/var/lib/k3/imagesموجود است؟ - فضای دیسک کافی است یا خیر؟
RegistryInspectFailure (500)
پیام: "Failed to inspect image from remote registry."
زمان رخ دادن: خطا در بررسی اطلاعات ایمیج از رجیستری دور
جزئیات:
{
"type": "NETWORK_ERROR",
"statusCode": 500,
"imageName": "nginx",
"imageTag": "latest",
"registry": "docker.io",
"error": "Registry connection failed"
}
راهنمای حل:
- اتصال اینترنت را بررسی کنید
- رجیستری دستیاب است یا خیر؟
- نام ایمیج درست است؟
- firewall یا proxy مسدود نمیکند؟
InsufficientDiskSpace (507)
پیام: "Insufficient disk space to pull image."
زمان رخ دادن: فضای دیسک برای دانلود ایمیج کافی نیست
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 507,
"imageName": "large-image",
"imageTag": "latest",
"requiredSpace": "2.5 GB",
"availableSpace": "1.8 GB",
"error": "Not enough disk space"
}
راهنمای حل:
- فضای دیسک کافی کنید (حداقل 2.5 برابر اندازه ایمیج)
- ایمیجهای قدیم را حذف کنید
- دسک دیگری استفاده کنید
ImagePullFailure (500)
پیام: "Failed to pull image from registry."
زمان رخ دادن: خطا در دانلود ایمیج
جزئیات:
{
"type": "NETWORK_ERROR",
"statusCode": 500,
"imageName": "myapp",
"imageTag": "v1.0",
"error": "Image not found in registry"
}
راهنمای حل:
- ایمیج در رجیستری موجود است یا خیر؟
- نام ایمیج و تگ درست است؟
- اتصال رجیستری برقرار است؟
- authentication diperlukan کنید؟
FindBlobsFailure (500)
پیام: "Failed to find image blobs."
زمان رخ دادن: خطا در یافتن blobهای ایمیج
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "postgres",
"imageTag": "15",
"error": "Blob scanning failed"
}
راهنمای حل:
- دایرکتوری ایمیج را بررسی کنید
- فایلهای blob موجود است؟
- دقیقترین را دنبال کنید
CreateImageBlobFailure (500)
پیام: "Failed to create blob record in database."
زمان رخ دادن: خطا در ایجاد رکورد blob در DB
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"imageName": "node",
"imageTag": "18",
"blobCount": 5,
"error": "Database write failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- فضای دیسک DB کافی است؟
- دیتابیس را restart کنید
CalculateImageSizeFailure (500)
پیام: "Failed to calculate image size."
زمان رخ دادن: خطا در محاسبه اندازه ایمیج
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "mysql",
"imageTag": "8.0",
"error": "Size calculation failed"
}
راهنمای حل:
- دایرکتوری ایمیج موجود است؟
- فایلها خراب نشدهاند؟
- اجازههای خواندن موجود است؟
FetchImageHistoryFailure (500)
پیام: "Failed to fetch image history."
زمان رخ دادن: خطا در دریافت تاریخچه ایمیج
جزئیات:
{
"type": "IMAGE_SERVICE_ERROR",
"statusCode": 500,
"imageName": "redis",
"imageTag": "latest",
"error": "History fetch failed"
}
راهنمای حل:
- ImageManager را بررسی کنید
- metadata ایمیج موجود است؟
- دوباره تلاش کنید
CreateImageRecordFailure (500)
پیام: "Failed to create image record in database."
زمان رخ دادن: خطا در ایجاد رکورد ایمیج در DB
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"imageName": "app",
"imageTag": "1.0",
"error": "Database write failed"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را restart کنید
- transaction logs را بررسی کنید
GenericFailure (500)
پیام: "Generic failure during image pull."
زمان رخ دادن: خطای عمومی
جزئیات:
{
"type": "GENERIC_ERROR",
"statusCode": 500,
"error": "Image pull failed"
}
راهنمای حل:
- سیستم لاگ را بررسی کنید
- تمام سرویسها را restart کنید
- دوباره تلاش کنید
مثالهای استفاده
مثال 1: دانلود ایمیج با تگ پیشفرض
const K3Core = require('k3-core');
(async () => {
const k3 = new K3Core();
try {
const result = await k3.imageCore.pullAnImage('alpine');
console.log(result);
// Output: alpine:latest has pulled successfully
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 2: دانلود ایمیج با تگ خاص
(async () => {
const k3 = new K3Core();
try {
const result = await k3.imageCore.pullAnImage('nginx', '1.25');
console.log(result);
// Output: nginx:1.25 has pulled successfully
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 3: دانلود ایمیج از رجیستری خاص
(async () => {
const k3 = new K3Core();
try {
const result = await k3.imageCore.pullAnImage('myregistry/myapp', 'v1.0');
console.log(result);
// Output: myregistry/myapp:v1.0 has pulled successfully
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 4: دانلود ایمیج با بررسی فضای دیسک
(async () => {
const k3 = new K3Core();
try {
const result = await k3.imageCore.pullAnImage('ubuntu', '22.04');
console.log('Pull successful:', result);
} catch (error) {
if (error.statusCode === 507) {
console.log('ERROR: Not enough disk space');
console.log('Required:', error.requiredSpace);
console.log('Available:', error.availableSpace);
} else {
console.log('Pull failed:', error.message);
}
}
})();
مثال 5: دانلود چند ایمیج
(async () => {
const k3 = new K3Core();
const images = [
{ name: 'alpine', tag: 'latest' },
{ name: 'nginx', tag: '1.25' },
{ name: 'node', tag: '18' }
];
const results = [];
for (const img of images) {
try {
const result = await k3.imageCore.pullAnImage(img.name, img.tag);
results.push({ status: 'success', message: result });
console.log(`✓ ${result}`);
} catch (error) {
results.push({ status: 'failed', error: error.message });
console.log(`✗ Failed to pull ${img.name}:${img.tag} - ${error.message}`);
}
}
console.log('\nSummary:');
const successful = results.filter(r => r.status === 'success').length;
const failed = results.filter(r => r.status === 'failed').length;
console.log(`Successful: ${successful}, Failed: ${failed}`);
})();
مثال 6: دانلود با بررسی موجودیت قبلی
(async () => {
const k3 = new K3Core();
const imageName = 'postgres';
const imageTag = '15';
try {
// بررسی اگر ایمیج قبلاً وجود دارد
const images = await k3.imageCore.listImages({
image: imageName,
tag: imageTag
});
if (images.length > 0) {
console.log(`Image ${imageName}:${imageTag} already exists`);
console.log('Skipping pull...');
return;
}
// دانلود ایمیج
const result = await k3.imageCore.pullAnImage(imageName, imageTag);
console.log('Pull result:', result);
} catch (error) {
console.log('ERROR:', error.message);
}
})();
مثال 7: دانلود ایمیج و ایجاد کانتینر
(async () => {
const k3 = new K3Core();
try {
// Pull ایمیج
const pullResult = await k3.imageCore.pullAnImage('alpine', 'latest');
console.log('Pull:', pullResult);
// Create و اجرای کانتینر
const containerResult = await k3.containerCore.runContainer({
containerId: 'my-alpine',
image: 'alpine',
tag: 'latest'
});
console.log('Container created:', containerResult);
} catch (error) {
console.log('ERROR:', error.createFullMessage());
}
})();
مثال 8: دانلود ایمیج با مدیریت خطاهای رایج
(async () => {
const k3 = new K3Core();
const pullImageWithErrorHandling = async (name, tag) => {
try {
const result = await k3.imageCore.pullAnImage(name, tag);
return { success: true, message: result };
} catch (error) {
if (error.statusCode === 409) {
console.log(`WARNING: Image ${name}:${tag} already exists`);
return { success: true, skipped: true, reason: 'Already exists' };
} else if (error.statusCode === 507) {
console.log(`ERROR: Not enough disk space for ${name}:${tag}`);
console.log(`Need: ${error.requiredSpace}, Have: ${error.availableSpace}`);
return { success: false, error: 'Insufficient disk space' };
} else if (error.statusCode === 500 && error.message.includes('not found')) {
console.log(`ERROR: Image ${name}:${tag} not found in registry`);
return { success: false, error: 'Image not found' };
} else {
console.log(`ERROR: Failed to pull ${name}:${tag}`);
return { success: false, error: error.message };
}
}
};
const result = await pullImageWithErrorHandling('myapp', 'v1.0');
console.log('Final result:', result);
})();
الگوهای خطا و راهنمای حل
الگو 1: ایمیج قبلاً موجود است
خطا: ImageAlreadyExists (409)
راهنمای حل:
const pullOrSkip = async (imageName, imageTag) => {
try {
const result = await k3.imageCore.pullAnImage(imageName, imageTag);
console.log('Pull successful:', result);
return true;
} catch (error) {
if (error.statusCode === 409) {
console.log(`Image ${imageName}:${imageTag} already exists locally`);
// اگر میخواهید بروزرسانی کنید:
console.log('Removing existing image...');
await k3.imageCore.removeAnImage(imageName, imageTag);
console.log('Pulling fresh image...');
const result = await k3.imageCore.pullAnImage(imageName, imageTag);
console.log('Pull successful:', result);
return true;
}
throw error;
}
};
await pullOrSkip('nginx', 'latest');
الگو 2: فضای دیسک ناکافی
خطا: InsufficientDiskSpace (507)
راهنمای حل:
const pullWithDiskCheck = async (imageName, imageTag) => {
try {
const result = await k3.imageCore.pullAnImage(imageName, imageTag);
return { success: true, message: result };
} catch (error) {
if (error.statusCode === 507) {
console.log('Insufficient disk space detected');
console.log(`Required: ${error.requiredSpace}`);
console.log(`Available: ${error.availableSpace}`);
// Cleanup old images
console.log('Attempting to free space...');
const images = await k3.imageCore.listImages({});
// Remove oldest or largest images
for (const img of images) {
if (shouldRemove(img)) {
await k3.imageCore.removeAnImage(img.Name, img.Tag);
console.log(`Removed ${img.Name}:${img.Tag}`);
}
}
// Retry pull
console.log('Retrying pull...');
const retryResult = await k3.imageCore.pullAnImage(imageName, imageTag);
return { success: true, message: retryResult, cleanedUp: true };
}
throw error;
}
};
const result = await pullWithDiskCheck('large-app', 'v1.0');
الگو 3: ایمیج در رجیستری یافت نشد
خطا: ImagePullFailure (500)
راهنمای حل:
const pullWithFallback = async (imageName, imageTag) => {
try {
const result = await k3.imageCore.pullAnImage(imageName, imageTag);
console.log('Pull successful:', result);
return result;
} catch (error) {
if (error.message.includes('not found')) {
console.log(`Image ${imageName}:${imageTag} not found`);
console.log('Trying alternative sources...');
// Try different registry
const alternatives = [
{ name: 'gcr.io/' + imageName, tag: imageTag },
{ name: 'quay.io/' + imageName, tag: imageTag },
{ name: imageName, tag: 'v' + imageTag } // try different tag
];
for (const alt of alternatives) {
try {
const result = await k3.imageCore.pullAnImage(alt.name, alt.tag);
console.log(`Found alternative: ${alt.name}:${alt.tag}`);
return result;
} catch (e) {
console.log(`Alternative ${alt.name}:${alt.tag} not found`);
}
}
throw new Error(`Could not find ${imageName}:${imageTag} anywhere`);
}
throw error;
}
};
await pullWithFallback('myapp', 'latest');
الگو 4: اتصال رجیستری قطع شد
خطا: RegistryInspectFailure (500)
راهنمای حل:
const pullWithRetry = async (imageName, imageTag, maxRetries = 3) => {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`Pull attempt ${attempt}/${maxRetries}: ${imageName}:${imageTag}`);
const result = await k3.imageCore.pullAnImage(imageName, imageTag);
console.log('Pull successful:', result);
return result;
} catch (error) {
lastError = error;
if (attempt < maxRetries) {
const waitTime = Math.pow(2, attempt) * 1000; // Exponential backoff
console.log(`Pull failed: ${error.message}`);
console.log(`Retrying in ${waitTime / 1000} seconds...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
}
throw lastError;
};
const result = await pullWithRetry('nginx', '1.25');
الگو 5: دانلود همزمان چند ایمیج با مدیریت منابع
راهنمای حل:
class ImagePullManager {
constructor(k3, maxConcurrent = 2) {
this.k3 = k3;
this.maxConcurrent = maxConcurrent;
this.queue = [];
this.active = 0;
this.results = [];
}
async pull(imageName, imageTag) {
return new Promise((resolve) => {
this.queue.push({ imageName, imageTag, resolve });
this.processQueue();
});
}
async processQueue() {
while (this.queue.length > 0 && this.active < this.maxConcurrent) {
this.active++;
const { imageName, imageTag, resolve } = this.queue.shift();
try {
const result = await this.k3.imageCore.pullAnImage(imageName, imageTag);
this.results.push({ status: 'success', imageName, imageTag, message: result });
console.log(`✓ ${result}`);
resolve({ success: true, message: result });
} catch (error) {
this.results.push({ status: 'failed', imageName, imageTag, error: error.message });
console.log(`✗ Failed to pull ${imageName}:${imageTag} - ${error.message}`);
resolve({ success: false, error: error.message });
}
this.active--;
this.processQueue();
}
}
getResults() {
return this.results;
}
}
const manager = new ImagePullManager(k3, 2);
await Promise.all([
manager.pull('alpine', 'latest'),
manager.pull('nginx', '1.25'),
manager.pull('node', '18'),
manager.pull('postgres', '15')
]);
console.log('Final results:', manager.getResults());
نکات عملی
-
فضای دیسک:
- حداقل 2.5 برابر اندازه ایمیج نیاز است
- برای ایمیجهای بزرگ (۱ GB+) خیلی زمانبر است
- فضای دیسک کافی کنید قبل از pull
-
اتصال شبکه:
- اتصال پایدار و سریع نیاز است
- proxy/firewall مسدود نباید کند
- authentication اگر registry private است
-
ایمیج موجود:
- نمیتوان ایمیج دوبار pull کنید
- برای بروزرسانی، حذف کنید و دوباره pull کنید
-
Performance:
- Pull زمانبر است، برای بهتری parallel انجام دهید
- maxConcurrent = 2-3 بهتری است
-
Registry:
- Docker Hub اگر نام داده نشود
- Private registry نیاز به credentials دارد
- نام کامل:
registry.com/repo/image:tag
-
Validation:
- نام و تگ قبل از pull بررسی شود
- ایمیج موجود بررسی شود (ImageAlreadyExists)
-
Logging:
- تمام pullها توسط سیستم log میشود
- برای audit، logها را ذخیره کنید
دنباله عملیات
- اعتبارسنجی پارامترها
- بررسی وجود ایمیج
- ایجاد دایرکتوری ایمیج اگر نیاز
- بررسی اطلاعات از رجیستری
- بررسی فضای دیسک
- دانلود ایمیج (skopeo)
- یافتن blobهای ایمیج
- ایجاد رکوردهای blob در DB
- محاسبه اندازه ایمیج
- دریافت تاریخچه ایمیج
- ایجاد رکورد ایمیج در DB
- Logging موفقیت
مرجع سریع
| وضعیت | کد | توضیح |
|---|---|---|
| موفق | 200 | ایمیج دانلود شد |
| پارامتر نامعتبر | 422 | InvalidImageNameOrTag |
| ایمیج موجود | 409 | ImageAlreadyExists |
| فضای کم | 507 | InsufficientDiskSpace |
| ایمیج یافت نشد | 500 | ImagePullFailure |
| خطای رجیستری | 500 | RegistryInspectFailure |
| خطای DB | 500 | CreateImageRecordFailure |
| خطای عمومی | 500 | GenericFailure |
موارد استفاده
Application Deployment
const result = await pullAnImage('myapp', 'v1.0');
Multi-Image Setup
const images = ['alpine', 'nginx', 'node'];
for (const img of images) {
await pullAnImage(img, 'latest');
}
CI/CD Pipeline
await pullAnImage('builder', buildVersion);
Development Environment
const result = await pullAnImage('postgres', '15');
نسخه: 1.3
تاریخ آپدیت: 10 آذرماه ۱۴۰۴
تیم توسعه: K3 Development Team