迁移背景:
从nexus 3.33 升级到 nexus 3.64 过程中,私服 npm-hosted 无法上传。由于这个 npm-hosted 和 npm-proxy 放的同一个 blob存储,无法单独拆除去,所以采用迁移的方式
迁移思路:
down下来 npm-hosted 仓库,然后 批量上传
技术栈:
python shell 正则
down仓库的python文件:
import os
import re
import requests
from urllib.parse import unquotedef decode_urls(url_list):decoded_urls = [unquote(url) for url in url_list]return decoded_urlsdef download_url(url, save_dir):response = requests.get(url)# 检查响应状态码if response.status_code == 200:# 获取URL的基本路径base_url = '/'.join(url.split('/')[:-1])# 解析HTML内容html_content = response.text# 搜索所有链接links = find_links(html_content)# 遍历链接for link in links:file_url = base_url +"/"+ link# 检查链接是否为目录if link.endswith('/'):# 创建本地目录save_subdir = os.path.join(save_dir, link)os.makedirs(save_subdir, exist_ok=True)# 递归下载子目录download_url(file_url, save_subdir)else:# 下载文件save_file = link.split("/")[-1]download_file(link, save_dir+save_file)else:print(f"Failed to download URL: {url}")def find_links(html_content):# 使用正则表达式或HTML解析库解析HTML内容,提取所有链接# 例如,可以使用正则表达式 r'<a\s+href=[\'"](.*?)[\'"]\s*>' 来提取链接# 返回一个包含所有链接的列表# 使用正则表达式匹配链接pattern = r'<a\s+href=[\'"](.*?)[\'"]\s*>'matches = re.findall(pattern, html_content)matches = decode_urls(matches)if '../' in matches:matches.remove('../')print(matches)# 返回匹配到的链接列表return matchesdef download_file(url, save_path):response = requests.get(url, stream=True)# 检查响应状态码if response.status_code == 200:with open(save_path, 'wb') as f:for chunk in response.iter_content(chunk_size=8192):f.write(chunk)else:print(f"Failed to download file: {url}")# 指定下载URL和保存目录
url = "https://mirrors.xinyunkeji.com/service/rest/repository/browse/npm-test-hosted/"
save_dir = '/opt/npm/download'# 创建保存目录(如果不存在)
os.makedirs(save_dir, exist_ok=True)# 开始下载
download_url(url, save_dir)
批量上传新仓库shell文件:
这个curl语句是从api接口里面,模拟上传一个文件,然后再下方获取的curl命令
#!/bin/bash
#需要上传到的仓库url
url='https://mirrors.xinyunkeji.com/service/rest/v1/components?repository=npm-test-hosted2'
#使用python下载的仓库目录
directory='/opt/npm/download'
#nexus有上传权限的账户密码
username='test'
password='mimaya'for file in $(find $directory -name "*.tgz"); doecho "准备上传${file}文件"curl -X POST $url \-H 'accept: application/json' \-H 'NX-ANTI-CSRF-TOKEN: 0.05104117117544127' \-H 'X-Nexus-UI: true' \-F "npm.asset=@$file;type=application/x-compressed" \-u "$username:$password"
done