Files
cherry-studio/resources/scripts/install-ovms.js
Kejiang Ma 2243bb2862 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>
2025-10-17 13:40:53 +08:00

264 lines
8.2 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const os = require('os')
const { execSync } = require('child_process')
const { downloadWithPowerShell } = require('./download')
// Base URL for downloading OVMS binaries
const OVMS_RELEASE_BASE_URL =
'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'
/**
* 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
*/
/**
* Clean old OVMS installation if it exists
*/
function cleanOldOvmsInstallation() {
console.log('Cleaning the existing OVMS installation...')
const csDir = path.join(os.homedir(), '.cherrystudio')
const csOvmsDir = path.join(csDir, 'ovms')
if (fs.existsSync(csOvmsDir)) {
try {
fs.rmSync(csOvmsDir, { recursive: true })
} catch (error) {
console.warn(`Failed to clean up old OVMS installation: ${error.message}`)
return 110
}
}
return 0
}
/**
* 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
}
// unzip the base package to the target directory
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
console.log(`Extracting OVMS Base 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: ${error.message}`)
fs.unlinkSync(tempFilename)
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
}
/**
* Get the CPU Name and ID
*/
function getCpuInfo() {
const cpuInfo = {
name: '',
id: ''
}
// Use PowerShell to get CPU information
try {
const psCommand = `powershell -Command "Get-CimInstance -ClassName Win32_Processor | Select-Object Name, DeviceID | ConvertTo-Json"`
const psOutput = execSync(psCommand).toString()
const cpuData = JSON.parse(psOutput)
if (Array.isArray(cpuData)) {
cpuInfo.name = cpuData[0].Name || ''
cpuInfo.id = cpuData[0].DeviceID || ''
} else {
cpuInfo.name = cpuData.Name || ''
cpuInfo.id = cpuData.DeviceID || ''
}
} catch (error) {
console.error(`Failed to get CPU info: ${error.message}`)
}
return cpuInfo
}
/**
* Main function to install OVMS
*/
async function installOvms() {
const platform = os.platform()
console.log(`Detected platform: ${platform}`)
const cpuName = getCpuInfo().name
console.log(`CPU Name: ${cpuName}`)
// Check if CPU name contains "Ultra"
if (!cpuName.toLowerCase().includes('intel') || !cpuName.toLowerCase().includes('ultra')) {
console.error('OVMS installation requires an Intel(R) Core(TM) Ultra CPU.')
return 101
}
// only support windows
if (platform !== 'win32') {
console.error('OVMS installation is only supported on Windows.')
return 102
}
// 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
installOvms()
.then((retcode) => {
if (retcode === 0) {
console.log('OVMS installation successful')
} else {
console.error('OVMS installation failed')
}
process.exit(retcode)
})
.catch((error) => {
console.error('OVMS installation failed:', error)
process.exit(100)
})