pinokiod 7.4.3 → 7.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/kernel/bin/conda-meta.js +13 -13
- package/kernel/bin/conda-pins.js +9 -7
- package/kernel/bin/conda.js +142 -203
- package/kernel/bin/cuda.js +7 -7
- package/kernel/bin/index.js +8 -12
- package/kernel/connect/providers/huggingface/index.js +4 -4
- package/kernel/index.js +0 -7
- package/kernel/shell.js +5 -4
- package/kernel/sysinfo.js +1 -1
- package/kernel/util.js +2 -2
- package/package.json +1 -1
- package/server/index.js +3 -4
- package/system/plugin/claude/pinokio.js +2 -2
- package/system/plugin/claude-auto/pinokio.js +2 -2
- package/system/plugin/codex/pinokio.js +1 -1
- package/system/plugin/codex-auto/pinokio.js +1 -1
- package/test/conda-bin.test.js +254 -0
- package/kernel/legacy_cleanup/ffmpeg.js +0 -133
- package/kernel/legacy_cleanup/index.js +0 -47
- package/test/legacy-cleanup.test.js +0 -161
package/kernel/bin/conda-meta.js
CHANGED
|
@@ -2,21 +2,21 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const { execFile } = require('child_process')
|
|
4
4
|
|
|
5
|
-
async function buildCondaListFromMeta(
|
|
5
|
+
async function buildCondaListFromMeta(condaRootPath, useCondaList) {
|
|
6
6
|
if (!useCondaList) {
|
|
7
|
-
const metaOutput = await readFromMeta(
|
|
7
|
+
const metaOutput = await readFromMeta(condaRootPath)
|
|
8
8
|
if (metaOutput) {
|
|
9
9
|
return { response: metaOutput, source: 'conda-meta' }
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
return await runCondaList(
|
|
12
|
+
return await runCondaList(condaRootPath)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
async function readFromMeta(
|
|
16
|
-
if (!
|
|
15
|
+
async function readFromMeta(condaRootPath) {
|
|
16
|
+
if (!condaRootPath) {
|
|
17
17
|
return null
|
|
18
18
|
}
|
|
19
|
-
const metaDir = path.join(
|
|
19
|
+
const metaDir = path.join(condaRootPath, 'conda-meta')
|
|
20
20
|
let entries
|
|
21
21
|
try {
|
|
22
22
|
entries = await fs.promises.readdir(metaDir, { withFileTypes: true })
|
|
@@ -53,8 +53,8 @@ async function readFromMeta(minicondaPath) {
|
|
|
53
53
|
return lines.join('\n')
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
async function runCondaList(
|
|
57
|
-
const condaBinary = resolveCondaBinary(
|
|
56
|
+
async function runCondaList(condaRootPath) {
|
|
57
|
+
const condaBinary = resolveCondaBinary(condaRootPath)
|
|
58
58
|
if (!condaBinary) {
|
|
59
59
|
return { response: '', source: 'conda-list' }
|
|
60
60
|
}
|
|
@@ -69,18 +69,18 @@ async function runCondaList(minicondaPath) {
|
|
|
69
69
|
})
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
function resolveCondaBinary(
|
|
72
|
+
function resolveCondaBinary(condaRootPath) {
|
|
73
73
|
if (process.platform === 'win32') {
|
|
74
|
-
if (
|
|
75
|
-
const scriptPath = path.join(
|
|
74
|
+
if (condaRootPath) {
|
|
75
|
+
const scriptPath = path.join(condaRootPath, 'Scripts', 'conda.exe')
|
|
76
76
|
if (fs.existsSync(scriptPath)) {
|
|
77
77
|
return scriptPath
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
return 'conda'
|
|
81
81
|
}
|
|
82
|
-
if (
|
|
83
|
-
const binPath = path.join(
|
|
82
|
+
if (condaRootPath) {
|
|
83
|
+
const binPath = path.join(condaRootPath, 'bin', 'conda')
|
|
84
84
|
if (fs.existsSync(binPath)) {
|
|
85
85
|
return binPath
|
|
86
86
|
}
|
package/kernel/bin/conda-pins.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const semver = require('semver')
|
|
2
2
|
|
|
3
|
-
const CONDA_PIN_VERSION = "
|
|
3
|
+
const CONDA_PIN_VERSION = "26.3.2"
|
|
4
4
|
const DEFAULT_SQLITE_PIN_VERSION = "3.47.2"
|
|
5
5
|
const WINDOWS_SQLITE_PIN_VERSION = "3.53.2"
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const PYTHON_PIN_VERSION = "3.10.20"
|
|
7
|
+
const PYTHON_INSTALL_SPEC = `python=${PYTHON_PIN_VERSION}`
|
|
8
|
+
const WINDOWS_PYTHON_SSL_FIX_SPEC = `${PYTHON_INSTALL_SPEC}=*_1_cpython`
|
|
8
9
|
|
|
9
10
|
const sqlitePinVersion = (platform) => {
|
|
10
11
|
return platform === "win32" ? WINDOWS_SQLITE_PIN_VERSION : DEFAULT_SQLITE_PIN_VERSION
|
|
@@ -28,15 +29,15 @@ const condaBuildNumber = (build) => {
|
|
|
28
29
|
return buildNumber ? Number(buildNumber) : null
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
const
|
|
32
|
+
const isExpectedPythonPinned = (platform, version, build) => {
|
|
32
33
|
const coerced = semver.coerce(version)
|
|
33
34
|
if (!coerced) {
|
|
34
35
|
return false
|
|
35
36
|
}
|
|
36
|
-
if (!semver.
|
|
37
|
+
if (!semver.eq(coerced, PYTHON_PIN_VERSION)) {
|
|
37
38
|
return false
|
|
38
39
|
}
|
|
39
|
-
if (
|
|
40
|
+
if (platform === "win32") {
|
|
40
41
|
const buildNumber = condaBuildNumber(build)
|
|
41
42
|
return typeof buildNumber === "number" && buildNumber >= 1
|
|
42
43
|
}
|
|
@@ -45,9 +46,10 @@ const isWindowsPythonSslFixed = (version, build) => {
|
|
|
45
46
|
|
|
46
47
|
module.exports = {
|
|
47
48
|
CONDA_PIN_VERSION,
|
|
49
|
+
PYTHON_INSTALL_SPEC,
|
|
48
50
|
WINDOWS_PYTHON_SSL_FIX_SPEC,
|
|
49
51
|
isExpectedSqlitePinned,
|
|
50
|
-
|
|
52
|
+
isExpectedPythonPinned,
|
|
51
53
|
sqliteInstallSpec,
|
|
52
54
|
sqlitePinnedSpec,
|
|
53
55
|
}
|
package/kernel/bin/conda.js
CHANGED
|
@@ -1,50 +1,41 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const fetch = require('cross-fetch')
|
|
4
3
|
const { glob } = require('glob')
|
|
5
4
|
const semver = require('semver')
|
|
6
5
|
const { buildCondaListFromMeta } = require('./conda-meta')
|
|
7
6
|
const {
|
|
8
7
|
CONDA_PIN_VERSION,
|
|
8
|
+
PYTHON_INSTALL_SPEC,
|
|
9
9
|
WINDOWS_PYTHON_SSL_FIX_SPEC,
|
|
10
|
+
isExpectedPythonPinned,
|
|
10
11
|
isExpectedSqlitePinned,
|
|
11
|
-
isWindowsPythonSslFixed,
|
|
12
12
|
sqliteInstallSpec,
|
|
13
13
|
sqlitePinnedSpec,
|
|
14
14
|
} = require('./conda-pins')
|
|
15
15
|
|
|
16
|
+
const MINIFORGE_RELEASE = "26.3.2-3"
|
|
17
|
+
const MINIFORGE_BASE_URL = `https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_RELEASE}`
|
|
18
|
+
const CONDA_ROOT_DIR = "miniforge"
|
|
19
|
+
const CONDA_COMPAT_ROOT_DIR = "miniconda"
|
|
20
|
+
const PINOKIO_CONDA_RUNTIME = {
|
|
21
|
+
distribution: "miniforge",
|
|
22
|
+
release: MINIFORGE_RELEASE,
|
|
23
|
+
epoch: 1,
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
class Conda {
|
|
17
27
|
description = "Pinokio uses Conda to install various useful programs in an isolated manner."
|
|
18
28
|
urls = {
|
|
19
29
|
darwin: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
//x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.5.0-0-MacOSX-x86_64.sh",
|
|
23
|
-
//arm64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.5.0-0-MacOSX-arm64.sh"
|
|
24
|
-
|
|
25
|
-
//x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.11.1-0-MacOSX-x86_64.sh",
|
|
26
|
-
//arm64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.11.1-0-MacOSX-arm64.sh"
|
|
27
|
-
|
|
28
|
-
x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_25.1.1-2-MacOSX-x86_64.sh",
|
|
29
|
-
arm64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_25.1.1-2-MacOSX-arm64.sh"
|
|
30
|
+
x64: `${MINIFORGE_BASE_URL}/Miniforge3-MacOSX-x86_64.sh`,
|
|
31
|
+
arm64: `${MINIFORGE_BASE_URL}/Miniforge3-MacOSX-arm64.sh`
|
|
30
32
|
},
|
|
31
33
|
win32: {
|
|
32
|
-
|
|
33
|
-
//x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.5.0-0-Windows-x86_64.exe"
|
|
34
|
-
|
|
35
|
-
//x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.11.1-0-Windows-x86_64.exe"
|
|
36
|
-
x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_25.1.1-2-Windows-x86_64.exe",
|
|
34
|
+
x64: `${MINIFORGE_BASE_URL}/Miniforge3-Windows-x86_64.exe`,
|
|
37
35
|
},
|
|
38
36
|
linux: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.5.0-0-Linux-x86_64.sh",
|
|
42
|
-
//arm64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.5.0-0-Linux-aarch64.sh"
|
|
43
|
-
|
|
44
|
-
//x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.11.1-0-Linux-x86_64.sh",
|
|
45
|
-
//arm64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_24.11.1-0-Linux-aarch64.sh"
|
|
46
|
-
x64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_25.1.1-2-Linux-x86_64.sh",
|
|
47
|
-
arm64: "https://repo.anaconda.com/miniconda/Miniconda3-py310_25.1.1-2-Linux-aarch64.sh"
|
|
37
|
+
x64: `${MINIFORGE_BASE_URL}/Miniforge3-Linux-x86_64.sh`,
|
|
38
|
+
arm64: `${MINIFORGE_BASE_URL}/Miniforge3-Linux-aarch64.sh`
|
|
48
39
|
}
|
|
49
40
|
}
|
|
50
41
|
installer = {
|
|
@@ -53,9 +44,9 @@ class Conda {
|
|
|
53
44
|
linux: "installer.sh"
|
|
54
45
|
}
|
|
55
46
|
paths = {
|
|
56
|
-
darwin: [
|
|
57
|
-
win32: [
|
|
58
|
-
linux: [
|
|
47
|
+
darwin: [ `${CONDA_ROOT_DIR}/etc/profile.d`, `${CONDA_ROOT_DIR}/bin`, `${CONDA_ROOT_DIR}/condabin`, `${CONDA_ROOT_DIR}/lib`, `${CONDA_ROOT_DIR}/Library/bin`, `${CONDA_ROOT_DIR}/pkgs`, CONDA_ROOT_DIR ],
|
|
48
|
+
win32: [`${CONDA_ROOT_DIR}/etc/profile.d`, `${CONDA_ROOT_DIR}/bin`, `${CONDA_ROOT_DIR}/Scripts`, `${CONDA_ROOT_DIR}/condabin`, `${CONDA_ROOT_DIR}/lib`, `${CONDA_ROOT_DIR}/Library/bin`, `${CONDA_ROOT_DIR}/pkgs`, CONDA_ROOT_DIR],
|
|
49
|
+
linux: [`${CONDA_ROOT_DIR}/etc/profile.d`, `${CONDA_ROOT_DIR}/bin`, `${CONDA_ROOT_DIR}/condabin`, `${CONDA_ROOT_DIR}/lib`, `${CONDA_ROOT_DIR}/Library/bin`, `${CONDA_ROOT_DIR}/pkgs`, CONDA_ROOT_DIR]
|
|
59
50
|
}
|
|
60
51
|
pinnedPackages() {
|
|
61
52
|
return [
|
|
@@ -63,25 +54,45 @@ class Conda {
|
|
|
63
54
|
sqlitePinnedSpec(this.kernel.platform),
|
|
64
55
|
].join("\n")
|
|
65
56
|
}
|
|
57
|
+
runtimeStampPath() {
|
|
58
|
+
return this.kernel.bin.path(CONDA_ROOT_DIR, ".pinokio-runtime.json")
|
|
59
|
+
}
|
|
60
|
+
async hasCurrentRuntimeStamp() {
|
|
61
|
+
try {
|
|
62
|
+
const value = await fs.promises.readFile(this.runtimeStampPath(), "utf8")
|
|
63
|
+
const runtime = JSON.parse(value)
|
|
64
|
+
return !!(runtime &&
|
|
65
|
+
runtime.distribution === PINOKIO_CONDA_RUNTIME.distribution &&
|
|
66
|
+
runtime.release === PINOKIO_CONDA_RUNTIME.release &&
|
|
67
|
+
runtime.epoch === PINOKIO_CONDA_RUNTIME.epoch)
|
|
68
|
+
} catch (e) {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async writeRuntimeStamp() {
|
|
73
|
+
await fs.promises.writeFile(
|
|
74
|
+
this.runtimeStampPath(),
|
|
75
|
+
`${JSON.stringify(PINOKIO_CONDA_RUNTIME, null, 2)}\n`
|
|
76
|
+
)
|
|
77
|
+
}
|
|
66
78
|
env() {
|
|
67
79
|
let base = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
PYTHON: this.kernel.bin.path("miniconda/python"),
|
|
80
|
+
CONDA_PREFIX: this.kernel.bin.path(CONDA_ROOT_DIR),
|
|
81
|
+
CONDA_ENVS_PATH: this.kernel.bin.path(`${CONDA_ROOT_DIR}/envs`),
|
|
82
|
+
CONDA_PKGS_DIRS: this.kernel.bin.path(`${CONDA_ROOT_DIR}/pkgs`),
|
|
83
|
+
PYTHON: this.kernel.bin.path(`${CONDA_ROOT_DIR}/python`),
|
|
73
84
|
PATH: this.paths[this.kernel.platform].map((p) => {
|
|
74
85
|
return this.kernel.bin.path(p)
|
|
75
86
|
})
|
|
76
87
|
}
|
|
77
88
|
if (this.kernel.platform === "win32") {
|
|
78
|
-
base.CONDA_BAT = this.kernel.bin.path(
|
|
79
|
-
base.CONDA_EXE = this.kernel.bin.path(
|
|
80
|
-
base.CONDA_PYTHON_EXE = this.kernel.bin.path(
|
|
89
|
+
base.CONDA_BAT = this.kernel.bin.path(`${CONDA_ROOT_DIR}/condabin/conda.bat`)
|
|
90
|
+
base.CONDA_EXE = this.kernel.bin.path(`${CONDA_ROOT_DIR}/Scripts/conda.exe`)
|
|
91
|
+
base.CONDA_PYTHON_EXE = this.kernel.bin.path(`${CONDA_ROOT_DIR}/Scripts/python`)
|
|
81
92
|
}
|
|
82
93
|
if (this.kernel.platform === 'darwin') {
|
|
83
|
-
base.TCL_LIBRARY = this.kernel.bin.path(
|
|
84
|
-
base.TK_LIBRARY = this.kernel.bin.path(
|
|
94
|
+
base.TCL_LIBRARY = this.kernel.bin.path(`${CONDA_ROOT_DIR}/lib/tcl8.6`)
|
|
95
|
+
base.TK_LIBRARY = this.kernel.bin.path(`${CONDA_ROOT_DIR}/lib/tk8.6`)
|
|
85
96
|
}
|
|
86
97
|
return base
|
|
87
98
|
}
|
|
@@ -89,7 +100,7 @@ class Conda {
|
|
|
89
100
|
if (this.kernel.platform !== "win32") {
|
|
90
101
|
return
|
|
91
102
|
}
|
|
92
|
-
const activateDir = this.kernel.bin.path(
|
|
103
|
+
const activateDir = this.kernel.bin.path(`${CONDA_ROOT_DIR}/etc/conda/activate.d`)
|
|
93
104
|
await fs.promises.mkdir(activateDir, { recursive: true }).catch(() => {})
|
|
94
105
|
await fs.promises.writeFile(
|
|
95
106
|
path.resolve(activateDir, "zz_pinokio_unset_ssl_cert_dir-win.bat"),
|
|
@@ -115,61 +126,31 @@ fi
|
|
|
115
126
|
)
|
|
116
127
|
}
|
|
117
128
|
async init() {
|
|
118
|
-
//
|
|
119
129
|
if (this.kernel.homedir) {
|
|
120
|
-
// let exists = await this.kernel.exists("condarc")
|
|
121
130
|
console.log("condarc init")
|
|
122
|
-
// if (!exists) {
|
|
123
131
|
await fs.promises.writeFile(this.kernel.path('condarc'), `channels:
|
|
124
132
|
- conda-forge
|
|
125
|
-
- defaults
|
|
126
133
|
channel_priority: flexible
|
|
127
134
|
create_default_packages:
|
|
128
|
-
-
|
|
135
|
+
- ${PYTHON_INSTALL_SPEC}
|
|
129
136
|
envs_dirs:
|
|
130
|
-
- ${this.kernel.bin.path(
|
|
131
|
-
plugins:
|
|
132
|
-
anaconda_telemetry: false
|
|
133
|
-
auto_accept_tos: true
|
|
137
|
+
- ${this.kernel.bin.path(`${CONDA_ROOT_DIR}/envs`)}
|
|
134
138
|
pkgs_dirs:
|
|
135
|
-
- ${this.kernel.bin.path(
|
|
139
|
+
- ${this.kernel.bin.path(`${CONDA_ROOT_DIR}/pkgs`)}
|
|
136
140
|
remote_connect_timeout_secs: 20.0
|
|
137
141
|
remote_read_timeout_secs: 300.0
|
|
138
142
|
remote_max_retries: 6
|
|
139
143
|
report_errors: false`)
|
|
140
|
-
|
|
141
|
-
//fetch_threads: 5
|
|
142
|
-
//report_errors: false`)
|
|
143
|
-
// }
|
|
144
|
-
let pinned_exists = await this.kernel.exists("bin/miniconda/conda-meta")
|
|
144
|
+
let pinned_exists = await this.kernel.exists(`bin/${CONDA_ROOT_DIR}/conda-meta`)
|
|
145
145
|
if (pinned_exists) {
|
|
146
|
-
|
|
147
|
-
await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), this.pinnedPackages())
|
|
148
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), "")
|
|
149
|
-
//sqlite ==3.47.2`)
|
|
150
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.9.0`)
|
|
151
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.11.2
|
|
152
|
-
//conda-libmamba-solver=24.11.1`)
|
|
153
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.7.1
|
|
154
|
-
//conda-libmamba-solver=24.7.0`)
|
|
146
|
+
await fs.promises.writeFile(this.kernel.path(`bin/${CONDA_ROOT_DIR}/conda-meta/pinned`), this.pinnedPackages())
|
|
155
147
|
}
|
|
156
148
|
await this.ensureSslCertDirOverride()
|
|
149
|
+
await this.ensureCompatibilityAlias()
|
|
157
150
|
}
|
|
158
151
|
}
|
|
159
|
-
// async init() {
|
|
160
|
-
// let exists = await this.kernel.bin.exists("miniconda/condarc")
|
|
161
|
-
// console.log("condarc exists?", exists)
|
|
162
|
-
// if (!exists) {
|
|
163
|
-
// console.log("write to condarc")
|
|
164
|
-
// await fs.promises.writeFile(this.kernel.bin.path('miniconda/condarc'), `channels:
|
|
165
|
-
// - conda-forge
|
|
166
|
-
// - defaults
|
|
167
|
-
// create_default_packages:
|
|
168
|
-
// - python=3.10`)
|
|
169
|
-
// }
|
|
170
|
-
// }
|
|
171
152
|
async check() {
|
|
172
|
-
let res = await buildCondaListFromMeta(this.kernel.bin.path(
|
|
153
|
+
let res = await buildCondaListFromMeta(this.kernel.bin.path(CONDA_ROOT_DIR))
|
|
173
154
|
|
|
174
155
|
let lines = res.response.split(/[\r\n]+/)
|
|
175
156
|
let conda_check = {}
|
|
@@ -189,20 +170,12 @@ report_errors: false`)
|
|
|
189
170
|
conda_builds[name] = build
|
|
190
171
|
if (name === "conda") {
|
|
191
172
|
conda_check.conda = true
|
|
192
|
-
// //if (String(version) === "24.11.1") {
|
|
193
|
-
// if (String(version) === "24.11.3") {
|
|
194
|
-
// conda_check.conda = true
|
|
195
|
-
// }
|
|
196
173
|
}
|
|
197
174
|
// check conda-libmamba-solver is up to date
|
|
198
175
|
// sometimes it just fails silently so need to check
|
|
199
176
|
if (name === "conda-libmamba-solver") {
|
|
200
|
-
//if (String(version) === "24.7.0") {
|
|
201
|
-
let channel = chunks[3]
|
|
202
177
|
let coerced = semver.coerce(version)
|
|
203
|
-
//let mamba_requirement = ">=24.11.1"
|
|
204
178
|
let mamba_requirement = ">=25.4.0"
|
|
205
|
-
//if (semver.satisfies(coerced, mamba_requirement) && channel === "conda-forge") {
|
|
206
179
|
if (semver.satisfies(coerced, mamba_requirement)) {
|
|
207
180
|
conda_check.mamba = true
|
|
208
181
|
}
|
|
@@ -225,7 +198,7 @@ report_errors: false`)
|
|
|
225
198
|
//}
|
|
226
199
|
}
|
|
227
200
|
if (name === "python") {
|
|
228
|
-
conda_check.python = this.kernel.platform
|
|
201
|
+
conda_check.python = isExpectedPythonPinned(this.kernel.platform, version, build)
|
|
229
202
|
}
|
|
230
203
|
}
|
|
231
204
|
} else {
|
|
@@ -237,8 +210,7 @@ report_errors: false`)
|
|
|
237
210
|
this.kernel.bin.installed.conda = conda
|
|
238
211
|
this.kernel.bin.installed.conda_versions = conda_versions
|
|
239
212
|
this.kernel.bin.installed.conda_builds = conda_builds
|
|
240
|
-
return conda_check.conda && conda_check.mamba && conda_check.sqlite &&
|
|
241
|
-
//return conda_check.conda && conda_check.mamba
|
|
213
|
+
return conda_check.conda && conda_check.mamba && conda_check.sqlite && conda_check.python
|
|
242
214
|
}
|
|
243
215
|
async install(req, ondata) {
|
|
244
216
|
for(let i=0; i<5; i++) {
|
|
@@ -255,12 +227,12 @@ report_errors: false`)
|
|
|
255
227
|
async _install(req, ondata) {
|
|
256
228
|
const installer_url = this.urls[this.kernel.platform][this.kernel.arch]
|
|
257
229
|
const installer = this.installer[this.kernel.platform]
|
|
258
|
-
const install_path = this.kernel.bin.path(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
230
|
+
const install_path = this.kernel.bin.path(CONDA_ROOT_DIR)
|
|
231
|
+
const compat_path = this.kernel.bin.path(CONDA_COMPAT_ROOT_DIR)
|
|
232
|
+
let install_path_exists = await this.kernel.exists(`bin/${CONDA_ROOT_DIR}`)
|
|
233
|
+
let compat_path_exists = await this.kernel.exists(`bin/${CONDA_COMPAT_ROOT_DIR}`)
|
|
234
|
+
if (install_path_exists || compat_path_exists) {
|
|
235
|
+
console.log("Install path already exists. Will replace after installer download...", install_path)
|
|
264
236
|
} else {
|
|
265
237
|
console.log("Install path does not exist. Installing...")
|
|
266
238
|
}
|
|
@@ -268,6 +240,17 @@ report_errors: false`)
|
|
|
268
240
|
ondata({ raw: `downloading installer: ${installer_url}...\r\n` })
|
|
269
241
|
await this.kernel.bin.download(installer_url, installer, ondata)
|
|
270
242
|
|
|
243
|
+
compat_path_exists = await this.kernel.exists(`bin/${CONDA_COMPAT_ROOT_DIR}`)
|
|
244
|
+
if (compat_path_exists) {
|
|
245
|
+
console.log("Removing compatibility install path...", compat_path)
|
|
246
|
+
await this.removeInstallPath(compat_path)
|
|
247
|
+
}
|
|
248
|
+
install_path_exists = await this.kernel.exists(`bin/${CONDA_ROOT_DIR}`)
|
|
249
|
+
if (install_path_exists) {
|
|
250
|
+
console.log("Removing existing install path...", install_path)
|
|
251
|
+
await this.removeInstallPath(install_path)
|
|
252
|
+
}
|
|
253
|
+
|
|
271
254
|
// 2. run the script
|
|
272
255
|
ondata({ raw: `running installer: ${installer}...\r\n` })
|
|
273
256
|
|
|
@@ -284,35 +267,13 @@ report_errors: false`)
|
|
|
284
267
|
})
|
|
285
268
|
|
|
286
269
|
// set pinned
|
|
287
|
-
let pinned_exists = await this.kernel.exists(
|
|
270
|
+
let pinned_exists = await this.kernel.exists(`bin/${CONDA_ROOT_DIR}/conda-meta`)
|
|
288
271
|
if (pinned_exists) {
|
|
289
|
-
|
|
290
|
-
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda ==24.11.3`)
|
|
291
|
-
await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), this.pinnedPackages())
|
|
292
|
-
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), "sqlite ==3.47.2")
|
|
293
|
-
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), "")
|
|
294
|
-
//sqlite ==3.47.2`)
|
|
295
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.9.0`)
|
|
296
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.11.2
|
|
297
|
-
//conda-libmamba-solver=24.11.1`)
|
|
298
|
-
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.7.1
|
|
299
|
-
//conda-libmamba-solver=24.7.0`)
|
|
272
|
+
await fs.promises.writeFile(this.kernel.path(`bin/${CONDA_ROOT_DIR}/conda-meta/pinned`), this.pinnedPackages())
|
|
300
273
|
}
|
|
301
|
-
//// await this.activate()
|
|
302
|
-
// await fs.promises.writeFile(this.kernel.bin.path('miniconda/condarc'), `channels:
|
|
303
|
-
// - conda-forge
|
|
304
|
-
// - defaults
|
|
305
|
-
//create_default_packages:
|
|
306
|
-
// - python=3.10`)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
// 1. right after installing conda==24.11.1, run conda update --all
|
|
310
|
-
// 2. The pinned file says conda-libmamba-solver=24.11.1
|
|
311
|
-
// 3. so after conda update --all, it should be conda-libmamba-solver=24.11.1
|
|
312
274
|
|
|
313
275
|
let mods = this.kernel.bin.mods.filter((m) => {
|
|
314
276
|
return req.dependencies.includes(m.name)
|
|
315
|
-
// return ["zip", "uv", "node", "huggingface", "gxx", "git", "ffmpeg", "caddy"].includes(m.name)
|
|
316
277
|
}).map((m) => {
|
|
317
278
|
if (m.mod.cmd) {
|
|
318
279
|
return m.mod.cmd()
|
|
@@ -323,113 +284,86 @@ report_errors: false`)
|
|
|
323
284
|
console.log("Conda dependencies to install", { mods })
|
|
324
285
|
|
|
325
286
|
let condaPackages = [
|
|
287
|
+
this.kernel.platform === "win32" ? `"${WINDOWS_PYTHON_SSL_FIX_SPEC}"` : `"${PYTHON_INSTALL_SPEC}"`,
|
|
326
288
|
`"${sqliteInstallSpec(this.kernel.platform)}"`,
|
|
327
289
|
`"conda-libmamba-solver>=25.4.0"`,
|
|
328
290
|
]
|
|
329
|
-
if (this.kernel.platform === "win32") {
|
|
330
|
-
condaPackages.unshift(`"${WINDOWS_PYTHON_SSL_FIX_SPEC}"`)
|
|
331
|
-
}
|
|
332
291
|
|
|
333
292
|
let cmds = [
|
|
334
|
-
//"conda clean -y --index-cache",
|
|
335
293
|
"conda clean -y --all",
|
|
336
|
-
`conda install -y -c conda-forge ${condaPackages.join(" ")} ${mods}`.trim(),
|
|
337
|
-
|
|
338
|
-
// `conda config --file ${this.kernel.path('condarc')} --set remote_connect_timeout_secs 20`,
|
|
339
|
-
// `conda config --file ${this.kernel.path('condarc')} --set remote_read_timeout_secs 300`,
|
|
340
|
-
// `conda config --file ${this.kernel.path('condarc')} --set remote_max_retries 6`,
|
|
341
|
-
// `conda config --file ${this.kernel.path('condarc')} --set repodata_threads 4`,
|
|
342
|
-
// `conda config --file ${this.kernel.path('condarc')} --set fetch_threads 5`,
|
|
343
|
-
// `conda config --file ${this.kernel.path('condarc')} --set report_errors false`,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
// `conda config --file ${this.kernel.path('condarc')} --set auto_update_conda false`,
|
|
348
|
-
// "conda install -y -c conda-forge conda-libmamba-solver=24.11.1",
|
|
349
|
-
// "conda install libsqlite --force-reinstall -y",
|
|
350
|
-
// `conda config --file ${this.kernel.path('condarc')} --set auto_update_conda False`,
|
|
351
|
-
//"conda install -y conda=24.9.0 -vvv --strict-channel-priority",
|
|
352
|
-
//"conda install -y conda=24.11.3 conda-libmamba-solver=24.11.1 -vvv",
|
|
353
|
-
//"conda install -y conda-libmamba-solver=24.7.0 conda=24.7.1 -vvv --strict-channel-priority",
|
|
354
|
-
//"conda install -y conda-libmamba-solver=24.11.1 conda=24.7.1",
|
|
355
|
-
//"conda install -y conda-libmamba-solver=24.11.1 conda=24.11.2",
|
|
356
|
-
//"conda update -y conda-libmamba-solver",
|
|
357
|
-
//"conda update -y conda sqlite",// -vvv --debug",
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
// "conda update -y conda",// -vvv --debug",
|
|
361
|
-
// "conda update -y --all",// -vvv --debug",
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
// "python -m pip install --upgrade pip setuptools wheel",
|
|
365
|
-
// "python -m ensurepip --upgrade",
|
|
366
|
-
// "conda update -y conda",
|
|
367
|
-
// "conda update -y --all",
|
|
294
|
+
`conda install -y --override-channels -c conda-forge ${condaPackages.join(" ")} ${mods}`.trim(),
|
|
368
295
|
]
|
|
369
|
-
//if (this.kernel.platform === "win32" || this.kernel.platform === "darwin") {
|
|
370
|
-
// cmds.push("conda install -y conda-libmamba-solver=24.7.0 conda=24.7.1 --freeze-installed")
|
|
371
|
-
//}
|
|
372
296
|
await this.kernel.bin.exec({
|
|
373
297
|
message: cmds,
|
|
374
298
|
env: {
|
|
375
299
|
PIP_REQUIRE_VIRTUALENV: "false"
|
|
376
300
|
}
|
|
377
|
-
// conda: {
|
|
378
|
-
// name: "base",
|
|
379
|
-
// activate: "minimal"
|
|
380
|
-
// }
|
|
381
|
-
// [
|
|
382
|
-
// (this.kernel.platform === 'win32' ? 'conda_hook' : `eval "$(conda shell.bash hook)"`),
|
|
383
|
-
// (this.platform === 'win32' ? `activate base` : `conda activate base`),
|
|
384
|
-
/*
|
|
385
|
-
`conda config --file ${this.kernel.bin.path('miniconda', 'condarc')} --remove channels conda-forge`,
|
|
386
|
-
`conda config --file ${this.kernel.bin.path('miniconda', 'condarc')} --remove channels defaults`,
|
|
387
|
-
`conda config --file ${this.kernel.bin.path('miniconda', 'condarc')} --prepend channels defaults`,
|
|
388
|
-
`conda config --file ${this.kernel.bin.path('miniconda', 'condarc')} --prepend channels conda-forge`,
|
|
389
|
-
`conda config --file ${this.kernel.bin.path('miniconda', 'condarc')} --add create_default_packages python=3.10`,
|
|
390
|
-
*/
|
|
391
|
-
//"conda update -y conda",
|
|
392
|
-
//"conda update -n base -c conda-forge -c defaults conda",
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
//"conda install conda=24.5.0",
|
|
396
|
-
// "conda clean -y --index-cache",
|
|
397
|
-
// "conda update -y --all",
|
|
398
|
-
// "conda install conda=24.9.0"
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
// handling the conda-libmamba-solver bug here: https://github.com/conda/conda-libmamba-solver/issues/283
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
// "conda remove -y libarchive",
|
|
405
|
-
// "conda install -y -c conda-forge libarchive",
|
|
406
|
-
// "conda install -y -c conda-forge pip brotli brotlipy",
|
|
407
|
-
// "conda install -y -c conda-forge libsqlite --force-reinstall",
|
|
408
|
-
// "conda install conda"
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
//"conda install -y -c conda-forge pip brotli brotlipy",
|
|
412
|
-
// "conda update --all",
|
|
413
|
-
// "conda update -y --all",
|
|
414
|
-
// ]
|
|
415
301
|
}, (stream) => {
|
|
416
302
|
ondata(stream)
|
|
417
303
|
})
|
|
418
304
|
if (this.kernel.platform === "win32") {
|
|
419
305
|
// copy python.exe to python3.exe so you can run with both python3 and python
|
|
420
306
|
await fs.promises.copyFile(
|
|
421
|
-
this.kernel.bin.path(
|
|
422
|
-
this.kernel.bin.path(
|
|
307
|
+
this.kernel.bin.path(CONDA_ROOT_DIR, "python.exe"),
|
|
308
|
+
this.kernel.bin.path(CONDA_ROOT_DIR, "python3.exe"),
|
|
423
309
|
)
|
|
424
310
|
}
|
|
425
311
|
await this.ensureSslCertDirOverride()
|
|
312
|
+
await this.writeRuntimeStamp()
|
|
313
|
+
await this.ensureCompatibilityAlias()
|
|
426
314
|
ondata({ raw: `Install finished\r\n` })
|
|
427
315
|
await this.kernel.bin.rm(installer, ondata)
|
|
428
316
|
}
|
|
317
|
+
async removeInstallPath(target) {
|
|
318
|
+
try {
|
|
319
|
+
const stat = await fs.promises.lstat(target).catch((error) => {
|
|
320
|
+
if (error && error.code === "ENOENT") {
|
|
321
|
+
return null
|
|
322
|
+
}
|
|
323
|
+
throw error
|
|
324
|
+
})
|
|
325
|
+
if (!stat) {
|
|
326
|
+
return
|
|
327
|
+
}
|
|
328
|
+
if (stat.isSymbolicLink()) {
|
|
329
|
+
await fs.promises.rm(target, { force: true })
|
|
330
|
+
return
|
|
331
|
+
}
|
|
332
|
+
await fs.promises.rm(target, {
|
|
333
|
+
recursive: true,
|
|
334
|
+
force: true,
|
|
335
|
+
maxRetries: 5,
|
|
336
|
+
retryDelay: 250,
|
|
337
|
+
})
|
|
338
|
+
} catch (error) {
|
|
339
|
+
const reason = error && (error.code || error.message) ? error.code || error.message : String(error)
|
|
340
|
+
throw new Error([
|
|
341
|
+
`Pinokio needs to replace the Conda runtime at ${target}, but it could not delete that folder.`,
|
|
342
|
+
"Close Pinokio and any terminals or editors using Pinokio, delete that folder manually, then reopen Pinokio.",
|
|
343
|
+
`Original error: ${reason}`,
|
|
344
|
+
].join("\n"))
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
async ensureCompatibilityAlias() {
|
|
348
|
+
const target = this.kernel.bin.path(CONDA_ROOT_DIR)
|
|
349
|
+
const alias = this.kernel.bin.path(CONDA_COMPAT_ROOT_DIR)
|
|
350
|
+
const targetExists = await fs.promises.access(target).then(() => true).catch(() => false)
|
|
351
|
+
if (!targetExists) {
|
|
352
|
+
return
|
|
353
|
+
}
|
|
354
|
+
const aliasExists = await fs.promises.lstat(alias).then(() => true).catch(() => false)
|
|
355
|
+
if (aliasExists) {
|
|
356
|
+
return
|
|
357
|
+
}
|
|
358
|
+
try {
|
|
359
|
+
await fs.promises.symlink(target, alias, this.kernel.platform === "win32" ? "junction" : "dir")
|
|
360
|
+
} catch (error) {
|
|
361
|
+
console.warn("Could not create Conda compatibility alias", error && error.message ? error.message : error)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
429
364
|
async exists(pattern) {
|
|
430
365
|
let paths = this.paths[this.kernel.platform]
|
|
431
366
|
for(let p of paths) {
|
|
432
|
-
//let e = await this.kernel.bin.exists(p + "/" + name)
|
|
433
367
|
const found = await glob(pattern, {
|
|
434
368
|
cwd: this.kernel.bin.path(p)
|
|
435
369
|
})
|
|
@@ -441,17 +375,22 @@ report_errors: false`)
|
|
|
441
375
|
}
|
|
442
376
|
|
|
443
377
|
async installed() {
|
|
444
|
-
let e
|
|
445
378
|
for(let p of this.paths[this.kernel.platform]) {
|
|
446
379
|
let e = await this.kernel.bin.exists(p)
|
|
447
|
-
if (e && this.kernel.bin.correct_conda)
|
|
380
|
+
if (e && this.kernel.bin.correct_conda) {
|
|
381
|
+
if (!(await this.hasCurrentRuntimeStamp())) {
|
|
382
|
+
console.log("Pinokio Conda runtime changed; marking Conda invalid")
|
|
383
|
+
return false
|
|
384
|
+
}
|
|
385
|
+
return true
|
|
386
|
+
}
|
|
448
387
|
}
|
|
449
388
|
return false
|
|
450
389
|
}
|
|
451
390
|
|
|
452
|
-
uninstall(req, ondata) {
|
|
453
|
-
|
|
454
|
-
return this.kernel.bin.rm(
|
|
391
|
+
async uninstall(req, ondata) {
|
|
392
|
+
await this.kernel.bin.rm(CONDA_COMPAT_ROOT_DIR, ondata)
|
|
393
|
+
return this.kernel.bin.rm(CONDA_ROOT_DIR, ondata)
|
|
455
394
|
}
|
|
456
395
|
|
|
457
396
|
onstart() {
|