您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show other mirrors to pull current docker image.
当前为
// ==UserScript== // @name Docker Hub Mirrors // @namespace https://github.com/iamspark1e/my-tampermonkey-scripts/blob/main/docker-mirror-urls.js // @version 0.1.1 // @description Show other mirrors to pull current docker image. // @author iamspark1e // @license AGPL-3.0-or-later // @match *://hub.docker.com/_/* // @match *://hub.docker.com/r/* // @grant GM_setValue // @grant GM_getValue // ==/UserScript== // ref: https://juejin.cn/post/7022654292880424991 // - 阿里云(杭州) https://registry.cn-hangzhou.aliyuncs.com // - 阿里云(上海) https://registry.cn-shanghai.aliyuncs.com // - 阿里云(青岛) https://registry.cn-qingdao.aliyuncs.com // - 阿里云(北京) https://registry.cn-beijing.aliyuncs.com // - 阿里云(张家口) https://registry.cn-zhangjiakou.aliyuncs.com // - 阿里云(呼和浩特) https://registry.cn-huhehaote.aliyuncs.com // - 阿里云(乌兰察布) https://registry.cn-wulanchabu.aliyuncs.com // - 阿里云(深圳) https://registry.cn-shenzhen.aliyuncs.com // - 阿里云(河源) https://registry.cn-heyuan.aliyuncs.com // - 阿里云(广州) https://registry.cn-guangzhou.aliyuncs.com // - 阿里云(成都) https://registry.cn-chengdu.aliyuncs.com // - 腾讯云 https://mirror.ccs.tencentyun.com // - 微软云 https://dockerhub.azk8s.com // - 网易 https://hub-mirror.c.163.com // - 上海交通大学 https://mirror.sjtu.edu.cn/docs/docker-registry // - ❤❤❤南京大学 https://docker.nju.edu.cn // - 道客 DaoCloud https://f1361db2.m.daocloud.io // - 阿里云(香港) https://registry.cn-hongkong.aliyuncs.com // - 阿里云(日本-东京) https://registry.ap-northeast-1.aliyuncs.com // - 阿里云(新加坡) https://registry.ap-southeast-1.aliyuncs.com // - 阿里云(澳大利亚-悉尼) https://registry.ap-southeast-2.aliyuncs.com // - 阿里云(马来西亚-吉隆坡) https://registry.ap-southeast-3.aliyuncs.com // - 阿里云(印度尼西亚-雅加达) https://registry.ap-southeast-5.aliyuncs.com // - 阿里云(印度-孟买) https://registry.ap-south-1.aliyuncs.com // - 阿里云(德国-法兰克福) https://registry.eu-central-1.aliyuncs.com // - 阿里云(英国-伦敦) https://registry.eu-west-1.aliyuncs.com // - 阿里云(美国西部-硅谷) https://registry.us-west-1.aliyuncs.com // - 阿里云(美国东部-弗吉尼亚) https://registry.us-east-1.aliyuncs.com // - 阿里云(阿联酋-迪拜) https://registry.me-east-1.aliyuncs.com // - 谷歌云 https://gcr.io // - 官方 https://registry.hub.docker.com (function () { 'use strict'; const ALTER_HUBS = [ { "url": "registry.cn-hangzhou.aliyuncs.com", "name": "阿里云(杭州)" }, { "url": "mirror.ccs.tencentyun.com", "name": "腾讯云" }, { "url": "dockerhub.azk8s.com", "name": "微软云(Azure)" }, { "url": "hub-mirror.c.163.com", "name": "网易" }, { "url": "mirror.sjtu.edu.cn/docs/docker-registry", "name": "上海交通大学" }, { "url": "docker.nju.edu.cn", "name": "南京大学" }, { "url": "f1361db2.m.daocloud.io", "name": "DaoCloud" }, { "url": "gcr.io", "name": "Google" }, { "url": "registry.hub.docker.com", "name": "官方" }, ] const DOM_IDENTIFIER = "iamspark1e_tampermonkey_docker_mirror_helper" const DOM_TPL = ` <label> <span>Choose a mirror: </span> <select> ${ALTER_HUBS.map(hub => `<option value="${hub.url}">${hub.name}</option>`).join("")} </select> </label> <div class="show_url" style="background-color:rgba(255,255,255,0.3);border-radius:4px;margin-top:4px;padding:4px;"></div> ` const GENERATE_SNIPPETS = (hub, image_name) => ` <p>URL: <span style="user-select:all;word-break:break-all;">${hub.url + '/' + image_name}</span></p> <p>Docker pull: <code style="user-select:all;word-break:break-all;">docker pull ${hub.url + '/' + image_name}</code></p> ` let siblingNode; let currentHub = ALTER_HUBS[0]; let imageFullName; let oldHref = window.location.href; function renderUrls() { let dom = document.querySelector(`#${DOM_IDENTIFIER} div.show_url`); dom.innerHTML = GENERATE_SNIPPETS(currentHub, imageFullName) } function selectHandler(e) { currentHub = ALTER_HUBS.find(hub => hub.url === e.target.value); renderUrls(); } function initHelper() { if (!siblingNode) { console.error("no siblingNode, init failed"); return; } const mountNode = siblingNode.parentNode.parentNode; imageFullName = siblingNode.innerText.replace("docker pull ", ""); if (!document.querySelector(`#${DOM_IDENTIFIER}`)) { const testDiv = document.createElement("div") testDiv.setAttribute("style", "border:1px solid #c4c8d1;background-color: #e1e2e6;border-radius: 4px;padding:8px;margin-top: 8px;"); testDiv.id = DOM_IDENTIFIER; testDiv.innerHTML = DOM_TPL; mountNode.appendChild(testDiv); // addEventListener const selector = document.querySelector(`#${DOM_IDENTIFIER} select`); selector.addEventListener("change", selectHandler); renderUrls(); } } let observer = new MutationObserver((mutationList, observer) => { if(oldHref !== window.location.href) { siblingNode = null; oldHref = window.location.href; } for (const mutation of mutationList) { if (mutation.type === "childList" && !siblingNode) { const tmp = document.querySelector('code[data-testid="copyPullCommandPullCommand"]') if (tmp && !siblingNode) { siblingNode = tmp; initHelper(); // observer.disconnect() } } } }); // *://hub.docker.com/_/* // *://hub.docker.com/r/* observer.observe(document.body, { childList: true, subtree: true }) // TODO: // *://hub.docker.com/_/*/tags // *://hub.docker.com/r/*/tags })();