迁移背景:
从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 unquote
def decode_urls(url_list):
decoded_urls = [unquote(url) for url in url_list]
return decoded_urls
def 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 matches
def 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"); do
echo "准备上传${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