Skip to content

Commit

Permalink
拉取镜像时提供响应支持
Browse files Browse the repository at this point in the history
  • Loading branch information
llody55 committed Oct 22, 2024
1 parent 6d48df9 commit 247a797
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 81 deletions.
6 changes: 5 additions & 1 deletion apps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,8 @@ def process_image(image):
code = 1
if e.status_code == 401 and "unauthorized: authentication required" in str(e):
msg = f"API错误:未授权失败,无法拉取!"
elif e.status_code == 404 and "Not Found tag" in str(e):
msg = f"API错误:未找到latest版本,请补全镜像版本!"
else:
msg = f"API错误:{e.explanation}"
except ConnectionError:
Expand Down Expand Up @@ -1223,7 +1225,7 @@ def docker_rollback_api(request):
if not success:
result = {'code': 1, 'msg': '无法连接到Docker'}
return JsonResponse(result)
# 获取指定容器
# 获取指定容器
container = client.containers.get(rollback_name)
# 获取当前容器正在使用的镜像
current_image_name = container.attrs['Config']['Image']
Expand Down Expand Up @@ -1728,6 +1730,8 @@ def docker_event_api(request):
event_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(event_dict.get('time')))
dat = {"id":id,"container_name":container_name,"status":status,"froms":froms,"event_time":event_time}
data.append(dat)
# 倒序排列事件
data.sort(key=lambda x: x['event_time'], reverse=True) # 按照事件时间倒序排序
events.close()
code = 0
msg = "数据获取成功"
Expand Down
120 changes: 61 additions & 59 deletions templates/images/images_pull.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
return;
}

console.log("镜像:" + imageName + "地址:" + registryUrl )
//console.log("镜像:" + imageName + "地址:" + registryUrl )
output.innerHTML = ''; // 清空之前的日志
logEntries = {}; // 清空之前的日志条目
socket.send(JSON.stringify({
Expand All @@ -136,76 +136,78 @@

socket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data.message;

if (message.id) {
if (!logEntries[message.id]) {
// 创建新的日志条目
var logEntry = document.createElement('div');
logEntry.classList.add('log-entry');
logEntry.setAttribute('id', 'log-' + message.id);

var status = document.createElement('p');
status.innerHTML = '<strong>ID:</strong> ' + message.id + ' <strong>Status:</strong> ' + message.status;
logEntry.appendChild(status);

if (message.progressDetail && message.progressDetail.total > 0) {
var progress = (message.progressDetail.current / message.progressDetail.total * 100).toFixed(2);
var progressBarContainer = document.createElement('div');
progressBarContainer.classList.add('layui-progress', 'progress-container');
progressBarContainer.setAttribute('lay-showPercent', 'true');

var progressBar = document.createElement('div');
progressBar.classList.add('layui-progress-bar');
progressBar.setAttribute('lay-percent', progress + '%');
progressBar.style.width = progress + '%';

progressBarContainer.appendChild(progressBar);
logEntry.appendChild(progressBarContainer);
}

output.appendChild(logEntry);
logEntries[message.id] = logEntry;
layui.element.init(); // 重新初始化进度条
} else {
// 更新现有的日志条目
var existingEntry = logEntries[message.id];
existingEntry.querySelector('p').innerHTML = '<strong>ID:</strong> ' + message.id + ' <strong>Status:</strong> ' + message.status;
if (message.progressDetail && message.progressDetail.total > 0) {
var progress = (message.progressDetail.current / message.progressDetail.total * 100).toFixed(2);
var progressBar = existingEntry.querySelector('.layui-progress-bar');
if (!progressBar) {
// 如果进度条不存在,创建新的进度条

if (data.error) {
// 处理错误信息
var errorStatus = document.createElement('div');
errorStatus.classList.add('log-entry', 'layui-bg-red'); // 添加红色背景表示错误
errorStatus.innerHTML = '<p><strong>Error:</strong> ' + data.error + '</p>';
output.appendChild(errorStatus);
} else if (data.message) {
var message = data.message;

if (message.id) {
if (!logEntries[message.id]) {
// 创建新的日志条目
var logEntry = document.createElement('div');
logEntry.classList.add('log-entry');
logEntry.setAttribute('id', 'log-' + message.id);

var status = document.createElement('p');
status.innerHTML = '<strong>ID:</strong> ' + message.id + ' <strong>Status:</strong> ' + message.status;
logEntry.appendChild(status);

if (message.progressDetail && message.progressDetail.total > 0) {
var progress = (message.progressDetail.current / message.progressDetail.total * 100).toFixed(2);
var progressBarContainer = document.createElement('div');
progressBarContainer.classList.add('layui-progress', 'progress-container');
progressBarContainer.setAttribute('lay-showPercent', 'true');

progressBar = document.createElement('div');
var progressBar = document.createElement('div');
progressBar.classList.add('layui-progress-bar');
progressBar.setAttribute('lay-percent', progress + '%');
progressBar.style.width = progress + '%';

progressBarContainer.appendChild(progressBar);
existingEntry.appendChild(progressBarContainer);
} else {
progressBar.setAttribute('lay-percent', progress + '%');
progressBar.style.width = progress + '%';
logEntry.appendChild(progressBarContainer);
}

output.appendChild(logEntry);
logEntries[message.id] = logEntry;
layui.element.init(); // 重新初始化进度条
} else {
// 更新现有的日志条目
var existingEntry = logEntries[message.id];
existingEntry.querySelector('p').innerHTML = '<strong>ID:</strong> ' + message.id + ' <strong>Status:</strong> ' + message.status;
if (message.progressDetail && message.progressDetail.total > 0) {
var progress = (message.progressDetail.current / message.progressDetail.total * 100).toFixed(2);
var progressBar = existingEntry.querySelector('.layui-progress-bar');
if (!progressBar) {
var progressBarContainer = document.createElement('div');
progressBarContainer.classList.add('layui-progress', 'progress-container');
progressBarContainer.setAttribute('lay-showPercent', 'true');

progressBar = document.createElement('div');
progressBar.classList.add('layui-progress-bar');
progressBar.setAttribute('lay-percent', progress + '%');
progressBar.style.width = progress + '%';

progressBarContainer.appendChild(progressBar);
existingEntry.appendChild(progressBarContainer);
} else {
progressBar.setAttribute('lay-percent', progress + '%');
progressBar.style.width = progress + '%';
}
layui.element.init(); // 重新初始化进度条
}
}
}
} else {
// 处理最终结果的情况
var finalStatus = document.createElement('div');
finalStatus.classList.add('log-entry');
finalStatus.innerHTML = '<p><strong>Final Status:</strong> ' + message.status + '</p>';
if (message.error) {
finalStatus.innerHTML += '<p><strong>Error:</strong> ' + message.error + '</p>';
finalStatus.classList.add('layui-bg-red'); // 添加红色背景表示错误
} else {
finalStatus.classList.add('layui-bg-green'); // 添加绿色背景表示成功
// 处理没有ID的消息
var noIdStatus = document.createElement('div');
noIdStatus.classList.add('log-entry');
noIdStatus.innerHTML = '<p><strong>Status:</strong> ' + message.status + '</p>';
output.appendChild(noIdStatus);
}
output.appendChild(finalStatus);
}
};

Expand Down
20 changes: 11 additions & 9 deletions udockers/contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ def version(request):
# 检查GitHub中版本
def get_latest_github_version(owner, repo):
url = f'https://api.github.com/repos/{owner}/{repo}/tags'
response = requests.get(url)
if response.status_code == 200:
tags = response.json()
if tags:
latest_tag = tags[0]['name']
# 去掉前缀 'v'
if latest_tag.startswith('v'):
latest_tag = latest_tag[1:]
return latest_tag
try:
response = requests.get(url, timeout=10) # 加入超时设置
if response.status_code == 200:
tags = response.json()
if tags:
latest_tag = tags[0]['name']
if latest_tag.startswith('v'):
latest_tag = latest_tag[1:]
return latest_tag
except requests.exceptions.RequestException as e:
print(f"Error fetching version from GitHub: {e}")
return None

def latest_version(request):
Expand Down
48 changes: 36 additions & 12 deletions udockers/websocket/docker_image_pull_consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from apps.models import CustomUser,Role,Registries,HostMonitoring
# 引用验证是否开启TLS认证的公共模块
from apps.docker_mod import connect_to_docker
from docker.errors import APIError, ImageNotFound,NotFound,DockerException
from loguru import logger

class DockerPullConsumer(WebsocketConsumer):
Expand All @@ -29,20 +30,43 @@ def receive(self, text_data):
raw_password = docker_mod.decrypt_password(encrypted_password, key)
# 同步方法
# 容器管理模块API
logger.error(image_name)
# logger.error(image_name)
success, client = docker_mod.connect_to_docker()
if success:
# 登录私有镜像仓库
login_result = client.login(username, raw_password, registry=registry_url)
print("登录结果:", login_result)
for line in client.api.pull(image_name, stream=True, decode=True):
self.send(text_data=json.dumps({
'message': line
}))
try:
# 登录私有镜像仓库
login_result = client.login(username, raw_password, registry=registry_url)
if login_result.get('Status') != 'Login Succeeded':
raise DockerException('登录失败,请检查用户名和密码。')
for line in client.api.pull(image_name, stream=True, decode=True):
self.send(text_data=json.dumps({
'message': line
}))
except NotFound as e:
self.send(text_data=json.dumps({'error': '镜像未找到,请检查镜像名称或tag。'}))
except APIError as e:
logger.error(e)
if e.status_code == 500 and "You may not login yet" in str(e):
self.send(text_data=json.dumps({'error': f'连接被拒绝:您可能尚未登录,或者登录信息不正确!!!'}))
else:
self.send(text_data=json.dumps({'error': f'发生错误: {str(e)}'}))
except DockerException as e:
self.send(text_data=json.dumps({'error': f'登录错误: {str(e)}'}))
except Exception as e:
self.send(text_data=json.dumps({'error': f'发生错误: {str(e)}'}))
else:
success, client = connect_to_docker()
if success:
for line in client.api.pull(image_name, stream=True, decode=True):
self.send(text_data=json.dumps({
'message': line
}))
try:
for line in client.api.pull(image_name, stream=True, decode=True):
self.send(text_data=json.dumps({
'message': line
}))
except NotFound as e:
self.send(text_data=json.dumps({'error': '镜像未找到,请检查镜像名称或tag。'}))
except APIError as e:
logger.error(e)
if e.status_code == 500 and "You may not login yet" in str(e):
self.send(text_data=json.dumps({'error': f'连接被拒绝:您可能尚未登录,或者登录信息不正确!!!'}))
except Exception as e:
self.send(text_data=json.dumps({'error': f'发生错误: {str(e)}'}))

0 comments on commit 247a797

Please sign in to comment.