mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-23 01:50:13 +08:00
feat: update and download ovms to 2025.3 official release from offici… (#10603)
* feat: update and download ovms to 2025.3 official release from official site. Signed-off-by: Kejiang Ma <kj.ma@intel.com> * fix UI text Signed-off-by: Kejiang Ma <kj.ma@intel.com> --------- Signed-off-by: Kejiang Ma <kj.ma@intel.com>
This commit is contained in:
parent
1f7d2fa93f
commit
2243bb2862
@ -5,105 +5,171 @@ const { execSync } = require('child_process')
|
|||||||
const { downloadWithPowerShell } = require('./download')
|
const { downloadWithPowerShell } = require('./download')
|
||||||
|
|
||||||
// Base URL for downloading OVMS binaries
|
// Base URL for downloading OVMS binaries
|
||||||
const OVMS_PKG_NAME = 'ovms250911.zip'
|
const OVMS_RELEASE_BASE_URL =
|
||||||
const OVMS_RELEASE_BASE_URL = [`https://gitcode.com/gcw_ggDjjkY3/kjfile/releases/download/download/${OVMS_PKG_NAME}`]
|
'https://storage.openvinotoolkit.org/repositories/openvino_model_server/packages/2025.3.0/ovms_windows_python_on.zip'
|
||||||
|
const OVMS_EX_URL = 'https://gitcode.com/gcw_ggDjjkY3/kjfile/releases/download/download/ovms_25.3_ex.zip'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads and extracts the OVMS binary for the specified platform
|
* error code:
|
||||||
|
* 101: Unsupported CPU (not Intel Ultra)
|
||||||
|
* 102: Unsupported platform (not Windows)
|
||||||
|
* 103: Download failed
|
||||||
|
* 104: Installation failed
|
||||||
|
* 105: Failed to create ovdnd.exe
|
||||||
|
* 106: Failed to create run.bat
|
||||||
|
* 110: Cleanup of old installation failed
|
||||||
*/
|
*/
|
||||||
async function downloadOvmsBinary() {
|
|
||||||
// Create output directory structure - OVMS goes into its own subdirectory
|
/**
|
||||||
|
* Clean old OVMS installation if it exists
|
||||||
|
*/
|
||||||
|
function cleanOldOvmsInstallation() {
|
||||||
|
console.log('Cleaning the existing OVMS installation...')
|
||||||
const csDir = path.join(os.homedir(), '.cherrystudio')
|
const csDir = path.join(os.homedir(), '.cherrystudio')
|
||||||
|
|
||||||
// Ensure directories exist
|
|
||||||
fs.mkdirSync(csDir, { recursive: true })
|
|
||||||
|
|
||||||
const csOvmsDir = path.join(csDir, 'ovms')
|
const csOvmsDir = path.join(csDir, 'ovms')
|
||||||
// Delete existing OVMS directory if it exists
|
|
||||||
if (fs.existsSync(csOvmsDir)) {
|
if (fs.existsSync(csOvmsDir)) {
|
||||||
fs.rmSync(csOvmsDir, { recursive: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
const tempdir = os.tmpdir()
|
|
||||||
const tempFilename = path.join(tempdir, 'ovms.zip')
|
|
||||||
|
|
||||||
// Try each URL until one succeeds
|
|
||||||
let downloadSuccess = false
|
|
||||||
let lastError = null
|
|
||||||
|
|
||||||
for (let i = 0; i < OVMS_RELEASE_BASE_URL.length; i++) {
|
|
||||||
const downloadUrl = OVMS_RELEASE_BASE_URL[i]
|
|
||||||
console.log(`Attempting download from URL ${i + 1}/${OVMS_RELEASE_BASE_URL.length}: ${downloadUrl}`)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`Downloading OVMS from ${downloadUrl} to ${tempFilename}...`)
|
fs.rmSync(csOvmsDir, { recursive: true })
|
||||||
|
|
||||||
// Try PowerShell download first, fallback to Node.js download if it fails
|
|
||||||
await downloadWithPowerShell(downloadUrl, tempFilename)
|
|
||||||
|
|
||||||
// If we get here, download was successful
|
|
||||||
downloadSuccess = true
|
|
||||||
console.log(`Successfully downloaded from: ${downloadUrl}`)
|
|
||||||
break
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Download failed from ${downloadUrl}: ${error.message}`)
|
console.warn(`Failed to clean up old OVMS installation: ${error.message}`)
|
||||||
lastError = error
|
return 110
|
||||||
|
|
||||||
// Clean up failed download file if it exists
|
|
||||||
if (fs.existsSync(tempFilename)) {
|
|
||||||
try {
|
|
||||||
fs.unlinkSync(tempFilename)
|
|
||||||
} catch (cleanupError) {
|
|
||||||
console.warn(`Failed to clean up temporary file: ${cleanupError.message}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue to next URL if this one failed
|
|
||||||
if (i < OVMS_RELEASE_BASE_URL.length - 1) {
|
|
||||||
console.log(`Trying next URL...`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if any download succeeded
|
return 0
|
||||||
if (!downloadSuccess) {
|
}
|
||||||
console.error(`All download URLs failed. Last error: ${lastError?.message || 'Unknown error'}`)
|
|
||||||
|
/**
|
||||||
|
* Install OVMS Base package
|
||||||
|
*/
|
||||||
|
async function installOvmsBase() {
|
||||||
|
// Download the base package
|
||||||
|
const tempdir = os.tmpdir()
|
||||||
|
const tempFilename = path.join(tempdir, 'ovms.zip')
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`Downloading OVMS Base Package from ${OVMS_RELEASE_BASE_URL} to ${tempFilename}...`)
|
||||||
|
|
||||||
|
// Try PowerShell download first, fallback to Node.js download if it fails
|
||||||
|
await downloadWithPowerShell(OVMS_RELEASE_BASE_URL, tempFilename)
|
||||||
|
console.log(`Successfully downloaded from: ${OVMS_RELEASE_BASE_URL}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Download OVMS Base failed: ${error.message}`)
|
||||||
|
fs.unlinkSync(tempFilename)
|
||||||
return 103
|
return 103
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// unzip the base package to the target directory
|
||||||
console.log(`Extracting to ${csDir}...`)
|
const csDir = path.join(os.homedir(), '.cherrystudio')
|
||||||
|
const csOvmsDir = path.join(csDir, 'ovms')
|
||||||
|
fs.mkdirSync(csOvmsDir, { recursive: true })
|
||||||
|
|
||||||
|
try {
|
||||||
// Use tar.exe to extract the ZIP file
|
// Use tar.exe to extract the ZIP file
|
||||||
console.log(`Extracting OVMS to ${csDir}...`)
|
console.log(`Extracting OVMS Base to ${csOvmsDir}...`)
|
||||||
execSync(`tar -xf ${tempFilename} -C ${csDir}`, { stdio: 'inherit' })
|
execSync(`tar -xf ${tempFilename} -C ${csOvmsDir}`, { stdio: 'inherit' })
|
||||||
console.log(`OVMS extracted to ${csDir}`)
|
console.log(`OVMS extracted to ${csOvmsDir}`)
|
||||||
|
|
||||||
// Clean up temporary file
|
// Clean up temporary file
|
||||||
fs.unlinkSync(tempFilename)
|
fs.unlinkSync(tempFilename)
|
||||||
console.log(`Installation directory: ${csDir}`)
|
console.log(`Installation directory: ${csDir}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error installing OVMS: ${error.message}`)
|
console.error(`Error installing OVMS: ${error.message}`)
|
||||||
if (fs.existsSync(tempFilename)) {
|
fs.unlinkSync(tempFilename)
|
||||||
fs.unlinkSync(tempFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if ovmsDir is empty and remove it if so
|
|
||||||
try {
|
|
||||||
const ovmsDir = path.join(csDir, 'ovms')
|
|
||||||
const files = fs.readdirSync(ovmsDir)
|
|
||||||
if (files.length === 0) {
|
|
||||||
fs.rmSync(ovmsDir, { recursive: true })
|
|
||||||
console.log(`Removed empty directory: ${ovmsDir}`)
|
|
||||||
}
|
|
||||||
} catch (cleanupError) {
|
|
||||||
console.warn(`Warning: Failed to clean up directory: ${cleanupError.message}`)
|
|
||||||
return 105
|
|
||||||
}
|
|
||||||
|
|
||||||
return 104
|
return 104
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const csOvmsBinDir = path.join(csOvmsDir, 'ovms')
|
||||||
|
// copy ovms.exe to ovdnd.exe
|
||||||
|
try {
|
||||||
|
fs.copyFileSync(path.join(csOvmsBinDir, 'ovms.exe'), path.join(csOvmsBinDir, 'ovdnd.exe'))
|
||||||
|
console.log('Copied ovms.exe to ovdnd.exe')
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error copying ovms.exe to ovdnd.exe: ${error.message}`)
|
||||||
|
return 105
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy {csOvmsBinDir}/setupvars.bat to {csOvmsBinDir}/run.bat, and append the following lines to run.bat:
|
||||||
|
// del %USERPROFILE%\.cherrystudio\ovms_log.log
|
||||||
|
// ovms.exe --config_path models/config.json --rest_port 8000 --log_level DEBUG --log_path %USERPROFILE%\.cherrystudio\ovms_log.log
|
||||||
|
const runBatPath = path.join(csOvmsBinDir, 'run.bat')
|
||||||
|
try {
|
||||||
|
fs.copyFileSync(path.join(csOvmsBinDir, 'setupvars.bat'), runBatPath)
|
||||||
|
fs.appendFileSync(runBatPath, '\r\n')
|
||||||
|
fs.appendFileSync(runBatPath, 'del %USERPROFILE%\\.cherrystudio\\ovms_log.log\r\n')
|
||||||
|
fs.appendFileSync(
|
||||||
|
runBatPath,
|
||||||
|
'ovms.exe --config_path models/config.json --rest_port 8000 --log_level DEBUG --log_path %USERPROFILE%\\.cherrystudio\\ovms_log.log\r\n'
|
||||||
|
)
|
||||||
|
console.log(`Created run.bat at: ${runBatPath}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error creating run.bat: ${error.message}`)
|
||||||
|
return 106
|
||||||
|
}
|
||||||
|
|
||||||
|
// create {csOvmsBinDir}/models/config.json with content '{"model_config_list": []}'
|
||||||
|
const configJsonPath = path.join(csOvmsBinDir, 'models', 'config.json')
|
||||||
|
fs.mkdirSync(path.dirname(configJsonPath), { recursive: true })
|
||||||
|
fs.writeFileSync(configJsonPath, '{"mediapipe_config_list":[],"model_config_list":[]}')
|
||||||
|
console.log(`Created config file: ${configJsonPath}`)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install OVMS Extra package
|
||||||
|
*/
|
||||||
|
async function installOvmsExtra() {
|
||||||
|
// Download the extra package
|
||||||
|
const tempdir = os.tmpdir()
|
||||||
|
const tempFilename = path.join(tempdir, 'ovms_ex.zip')
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`Downloading OVMS Extra Package from ${OVMS_EX_URL} to ${tempFilename}...`)
|
||||||
|
|
||||||
|
// Try PowerShell download first, fallback to Node.js download if it fails
|
||||||
|
await downloadWithPowerShell(OVMS_EX_URL, tempFilename)
|
||||||
|
console.log(`Successfully downloaded from: ${OVMS_EX_URL}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Download OVMS Extra failed: ${error.message}`)
|
||||||
|
fs.unlinkSync(tempFilename)
|
||||||
|
return 103
|
||||||
|
}
|
||||||
|
|
||||||
|
// unzip the extra package to the target directory
|
||||||
|
const csDir = path.join(os.homedir(), '.cherrystudio')
|
||||||
|
const csOvmsDir = path.join(csDir, 'ovms')
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Use tar.exe to extract the ZIP file
|
||||||
|
console.log(`Extracting OVMS Extra to ${csOvmsDir}...`)
|
||||||
|
execSync(`tar -xf ${tempFilename} -C ${csOvmsDir}`, { stdio: 'inherit' })
|
||||||
|
console.log(`OVMS extracted to ${csOvmsDir}`)
|
||||||
|
|
||||||
|
// Clean up temporary file
|
||||||
|
fs.unlinkSync(tempFilename)
|
||||||
|
console.log(`Installation directory: ${csDir}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error installing OVMS Extra: ${error.message}`)
|
||||||
|
fs.unlinkSync(tempFilename)
|
||||||
|
return 104
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply ovms patch, copy all files in {csOvmsDir}/patch/ovms to {csOvmsDir}/ovms with overwrite mode
|
||||||
|
const patchDir = path.join(csOvmsDir, 'patch', 'ovms')
|
||||||
|
const csOvmsBinDir = path.join(csOvmsDir, 'ovms')
|
||||||
|
try {
|
||||||
|
const files = fs.readdirSync(patchDir)
|
||||||
|
files.forEach((file) => {
|
||||||
|
const srcPath = path.join(patchDir, file)
|
||||||
|
const destPath = path.join(csOvmsBinDir, file)
|
||||||
|
fs.copyFileSync(srcPath, destPath)
|
||||||
|
console.log(`Applied patch file: ${file}`)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error applying OVMS patch: ${error.message}`)
|
||||||
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +224,27 @@ async function installOvms() {
|
|||||||
return 102
|
return 102
|
||||||
}
|
}
|
||||||
|
|
||||||
return await downloadOvmsBinary()
|
// Clean old installation if it exists
|
||||||
|
const cleanupCode = cleanOldOvmsInstallation()
|
||||||
|
if (cleanupCode !== 0) {
|
||||||
|
console.error(`OVMS cleanup failed with code: ${cleanupCode}`)
|
||||||
|
return cleanupCode
|
||||||
|
}
|
||||||
|
|
||||||
|
const installBaseCode = await installOvmsBase()
|
||||||
|
if (installBaseCode !== 0) {
|
||||||
|
console.error(`OVMS Base installation failed with code: ${installBaseCode}`)
|
||||||
|
cleanOldOvmsInstallation()
|
||||||
|
return installBaseCode
|
||||||
|
}
|
||||||
|
|
||||||
|
const installExtraCode = await installOvmsExtra()
|
||||||
|
if (installExtraCode !== 0) {
|
||||||
|
console.error(`OVMS Extra installation failed with code: ${installExtraCode}`)
|
||||||
|
return installExtraCode
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the installation
|
// Run the installation
|
||||||
|
|||||||
@ -2110,8 +2110,10 @@
|
|||||||
"install_code_101": "Only supports Intel(R) Core(TM) Ultra CPU",
|
"install_code_101": "Only supports Intel(R) Core(TM) Ultra CPU",
|
||||||
"install_code_102": "Only supports Windows",
|
"install_code_102": "Only supports Windows",
|
||||||
"install_code_103": "Download OVMS runtime failed",
|
"install_code_103": "Download OVMS runtime failed",
|
||||||
"install_code_104": "Uncompress OVMS runtime failed",
|
"install_code_104": "Failed to install OVMS runtime",
|
||||||
"install_code_105": "Clean OVMS runtime failed",
|
"install_code_105": "Failed to create ovdnd.exe",
|
||||||
|
"install_code_106": "Failed to create run.bat",
|
||||||
|
"install_code_110": "Failed to clean old OVMS runtime",
|
||||||
"run": "Run OVMS failed:",
|
"run": "Run OVMS failed:",
|
||||||
"stop": "Stop OVMS failed:"
|
"stop": "Stop OVMS failed:"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2085,7 +2085,7 @@
|
|||||||
"description": "<div><p>1. 下载 OV 模型.</p><p>2. 在 'Manager' 中添加模型.</p><p>仅支持 Windows!</p><p>OVMS 安装路径: '%USERPROFILE%\\.cherrystudio\\ovms' .</p><p>请参考 <a href=https://github.com/openvinotoolkit/model_server/blob/c55551763d02825829337b62c2dcef9339706f79/docs/deploying_server_baremetal.md>Intel OVMS 指南</a></p></dev>",
|
"description": "<div><p>1. 下载 OV 模型.</p><p>2. 在 'Manager' 中添加模型.</p><p>仅支持 Windows!</p><p>OVMS 安装路径: '%USERPROFILE%\\.cherrystudio\\ovms' .</p><p>请参考 <a href=https://github.com/openvinotoolkit/model_server/blob/c55551763d02825829337b62c2dcef9339706f79/docs/deploying_server_baremetal.md>Intel OVMS 指南</a></p></dev>",
|
||||||
"download": {
|
"download": {
|
||||||
"button": "下载",
|
"button": "下载",
|
||||||
"error": "选择失败",
|
"error": "下载失败",
|
||||||
"model_id": {
|
"model_id": {
|
||||||
"label": "模型 ID",
|
"label": "模型 ID",
|
||||||
"model_id_pattern": "模型 ID 必须以 OpenVINO/ 开头",
|
"model_id_pattern": "模型 ID 必须以 OpenVINO/ 开头",
|
||||||
@ -2110,8 +2110,10 @@
|
|||||||
"install_code_101": "仅支持 Intel(R) Core(TM) Ultra CPU",
|
"install_code_101": "仅支持 Intel(R) Core(TM) Ultra CPU",
|
||||||
"install_code_102": "仅支持 Windows",
|
"install_code_102": "仅支持 Windows",
|
||||||
"install_code_103": "下载 OVMS runtime 失败",
|
"install_code_103": "下载 OVMS runtime 失败",
|
||||||
"install_code_104": "解压 OVMS runtime 失败",
|
"install_code_104": "安装 OVMS runtime 失败",
|
||||||
"install_code_105": "清理 OVMS runtime 失败",
|
"install_code_105": "创建 ovdnd.exe 失败",
|
||||||
|
"install_code_106": "创建 run.bat 失败",
|
||||||
|
"install_code_110": "清理旧 OVMS runtime 失败",
|
||||||
"run": "运行 OVMS 失败:",
|
"run": "运行 OVMS 失败:",
|
||||||
"stop": "停止 OVMS 失败:"
|
"stop": "停止 OVMS 失败:"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2085,7 +2085,7 @@
|
|||||||
"description": "<div><p>1. 下載 OV 模型。</p><p>2. 在 'Manager' 中新增模型。</p><p>僅支援 Windows!</p><p>OVMS 安裝路徑: '%USERPROFILE%\\.cherrystudio\\ovms' 。</p><p>請參考 <a href=https://github.com/openvinotoolkit/model_server/blob/c55551763d02825829337b62c2dcef9339706f79/docs/deploying_server_baremetal.md>Intel OVMS 指南</a></p></dev>",
|
"description": "<div><p>1. 下載 OV 模型。</p><p>2. 在 'Manager' 中新增模型。</p><p>僅支援 Windows!</p><p>OVMS 安裝路徑: '%USERPROFILE%\\.cherrystudio\\ovms' 。</p><p>請參考 <a href=https://github.com/openvinotoolkit/model_server/blob/c55551763d02825829337b62c2dcef9339706f79/docs/deploying_server_baremetal.md>Intel OVMS 指南</a></p></dev>",
|
||||||
"download": {
|
"download": {
|
||||||
"button": "下載",
|
"button": "下載",
|
||||||
"error": "選擇失敗",
|
"error": "下載失敗",
|
||||||
"model_id": {
|
"model_id": {
|
||||||
"label": "模型 ID",
|
"label": "模型 ID",
|
||||||
"model_id_pattern": "模型 ID 必須以 OpenVINO/ 開頭",
|
"model_id_pattern": "模型 ID 必須以 OpenVINO/ 開頭",
|
||||||
@ -2110,8 +2110,10 @@
|
|||||||
"install_code_101": "僅支援 Intel(R) Core(TM) Ultra CPU",
|
"install_code_101": "僅支援 Intel(R) Core(TM) Ultra CPU",
|
||||||
"install_code_102": "僅支援 Windows",
|
"install_code_102": "僅支援 Windows",
|
||||||
"install_code_103": "下載 OVMS runtime 失敗",
|
"install_code_103": "下載 OVMS runtime 失敗",
|
||||||
"install_code_104": "解壓 OVMS runtime 失敗",
|
"install_code_104": "安裝 OVMS runtime 失敗",
|
||||||
"install_code_105": "清理 OVMS runtime 失敗",
|
"install_code_105": "創建 ovdnd.exe 失敗",
|
||||||
|
"install_code_106": "創建 run.bat 失敗",
|
||||||
|
"install_code_110": "清理舊 OVMS runtime 失敗",
|
||||||
"run": "執行 OVMS 失敗:",
|
"run": "執行 OVMS 失敗:",
|
||||||
"stop": "停止 OVMS 失敗:"
|
"stop": "停止 OVMS 失敗:"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -36,7 +36,9 @@ const OVMSSettings: FC = () => {
|
|||||||
'102': t('ovms.failed.install_code_102'),
|
'102': t('ovms.failed.install_code_102'),
|
||||||
'103': t('ovms.failed.install_code_103'),
|
'103': t('ovms.failed.install_code_103'),
|
||||||
'104': t('ovms.failed.install_code_104'),
|
'104': t('ovms.failed.install_code_104'),
|
||||||
'105': t('ovms.failed.install_code_105')
|
'105': t('ovms.failed.install_code_105'),
|
||||||
|
'106': t('ovms.failed.install_code_106'),
|
||||||
|
'110': t('ovms.failed.install_code_110')
|
||||||
}
|
}
|
||||||
const match = error.message.match(/code (\d+)/)
|
const match = error.message.match(/code (\d+)/)
|
||||||
const code = match ? match[1] : 'unknown'
|
const code = match ? match[1] : 'unknown'
|
||||||
@ -135,7 +137,7 @@ const OVMSSettings: FC = () => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
onClick={runOvms}
|
onClick={runOvms}
|
||||||
loading={isRunningOvms}
|
loading={isRunningOvms}
|
||||||
disabled={isRunningOvms}
|
disabled={isRunningOvms || isInstallingOvms}
|
||||||
size="small">
|
size="small">
|
||||||
{isRunningOvms ? t('ovms.action.starting') : t('ovms.action.run')}
|
{isRunningOvms ? t('ovms.action.starting') : t('ovms.action.run')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user