pinokiod 7.5.30 → 7.5.31
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.js +77 -29
- package/kernel/bin/index.js +3 -0
- package/package.json +1 -1
- package/server/index.js +7 -0
- package/test/conda-bin.test.js +90 -41
package/kernel/bin/conda.js
CHANGED
|
@@ -14,6 +14,61 @@ const MINIFORGE_RELEASE = "26.3.2-3"
|
|
|
14
14
|
const MINIFORGE_BASE_URL = `https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_RELEASE}`
|
|
15
15
|
const CONDA_ROOT_DIR = "miniforge"
|
|
16
16
|
const LEGACY_CONDA_ROOT_DIR = "miniconda"
|
|
17
|
+
const WINDOWS_OPENSSL_HOOKS = {
|
|
18
|
+
activate: {
|
|
19
|
+
"openssl_activate-win.bat": [
|
|
20
|
+
"@echo off",
|
|
21
|
+
'if "%SSL_CERT_FILE%"=="" (',
|
|
22
|
+
' set "SSL_CERT_FILE=%CONDA_PREFIX%\\Library\\ssl\\cacert.pem"',
|
|
23
|
+
' set "__CONDA_OPENSSL_CERT_FILE_SET=1"',
|
|
24
|
+
")",
|
|
25
|
+
"",
|
|
26
|
+
].join("\r\n"),
|
|
27
|
+
"openssl_activate-win.ps1": [
|
|
28
|
+
"if (-not $Env:SSL_CERT_FILE) {",
|
|
29
|
+
' $Env:SSL_CERT_FILE = "$Env:CONDA_PREFIX\\Library\\ssl\\cacert.pem"',
|
|
30
|
+
' $Env:__CONDA_OPENSSL_CERT_FILE_SET = "1"',
|
|
31
|
+
"}",
|
|
32
|
+
"",
|
|
33
|
+
].join("\r\n"),
|
|
34
|
+
"openssl_activate-win.sh": [
|
|
35
|
+
'if [[ "${SSL_CERT_FILE:-}" == "" ]]; then',
|
|
36
|
+
' export SSL_CERT_FILE="${CONDA_PREFIX}\\\\Library\\\\ssl\\\\cacert.pem"',
|
|
37
|
+
' export __CONDA_OPENSSL_CERT_FILE_SET="1"',
|
|
38
|
+
"fi",
|
|
39
|
+
"",
|
|
40
|
+
].join("\n"),
|
|
41
|
+
},
|
|
42
|
+
deactivate: {
|
|
43
|
+
"openssl_deactivate-win.bat": [
|
|
44
|
+
"@echo off",
|
|
45
|
+
'if "%__CONDA_OPENSSL_CERT_FILE_SET%" == "1" (',
|
|
46
|
+
" set SSL_CERT_FILE=",
|
|
47
|
+
" set __CONDA_OPENSSL_CERT_FILE_SET=",
|
|
48
|
+
")",
|
|
49
|
+
"",
|
|
50
|
+
].join("\r\n"),
|
|
51
|
+
"openssl_deactivate-win.ps1": [
|
|
52
|
+
'if ($Env:__CONDA_OPENSSL_CERT_FILE_SET -eq "1") {',
|
|
53
|
+
" Remove-Item -Path Env:\\SSL_CERT_FILE",
|
|
54
|
+
" Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_FILE_SET",
|
|
55
|
+
"}",
|
|
56
|
+
"",
|
|
57
|
+
].join("\r\n"),
|
|
58
|
+
"openssl_deactivate-win.sh": [
|
|
59
|
+
'if [[ "${__CONDA_OPENSSL_CERT_FILE_SET:-}" == "1" ]]; then',
|
|
60
|
+
" unset SSL_CERT_FILE",
|
|
61
|
+
" unset __CONDA_OPENSSL_CERT_FILE_SET",
|
|
62
|
+
"fi",
|
|
63
|
+
"",
|
|
64
|
+
].join("\n"),
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
const LEGACY_SSL_CERT_DIR_HOOK_FILES = [
|
|
68
|
+
"zz_pinokio_unset_ssl_cert_dir-win.bat",
|
|
69
|
+
"zz_pinokio_unset_ssl_cert_dir-win.ps1",
|
|
70
|
+
"zz_pinokio_unset_ssl_cert_dir-win.sh",
|
|
71
|
+
]
|
|
17
72
|
|
|
18
73
|
class Conda {
|
|
19
74
|
description = "Pinokio uses Conda to install various useful programs in an isolated manner."
|
|
@@ -69,7 +124,7 @@ class Conda {
|
|
|
69
124
|
}
|
|
70
125
|
return base
|
|
71
126
|
}
|
|
72
|
-
async
|
|
127
|
+
async ensureWindowsOpenSslHooks() {
|
|
73
128
|
if (this.kernel.platform !== "win32") {
|
|
74
129
|
return
|
|
75
130
|
}
|
|
@@ -82,33 +137,26 @@ class Conda {
|
|
|
82
137
|
if (condaRootDirs.length === 0) {
|
|
83
138
|
return
|
|
84
139
|
}
|
|
85
|
-
const hookFiles = {
|
|
86
|
-
"zz_pinokio_unset_ssl_cert_dir-win.bat": `@echo off
|
|
87
|
-
if "%__CONDA_OPENSSL_CERT_DIR_SET%"=="1" (
|
|
88
|
-
set "SSL_CERT_DIR="
|
|
89
|
-
set "__CONDA_OPENSSL_CERT_DIR_SET="
|
|
90
|
-
)
|
|
91
|
-
`,
|
|
92
|
-
"zz_pinokio_unset_ssl_cert_dir-win.ps1": `if ($Env:__CONDA_OPENSSL_CERT_DIR_SET -eq "1") {
|
|
93
|
-
Remove-Item -Path Env:\\SSL_CERT_DIR -ErrorAction SilentlyContinue
|
|
94
|
-
Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_DIR_SET -ErrorAction SilentlyContinue
|
|
95
|
-
}
|
|
96
|
-
`,
|
|
97
|
-
"zz_pinokio_unset_ssl_cert_dir-win.sh": `if [[ "\${__CONDA_OPENSSL_CERT_DIR_SET:-}" == "1" ]]; then
|
|
98
|
-
unset SSL_CERT_DIR
|
|
99
|
-
unset __CONDA_OPENSSL_CERT_DIR_SET
|
|
100
|
-
fi
|
|
101
|
-
`,
|
|
102
|
-
}
|
|
103
140
|
for (const rootDir of condaRootDirs) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
141
|
+
const activateDir = this.kernel.bin.path(`${rootDir}/etc/conda/activate.d`)
|
|
142
|
+
const deactivateDir = this.kernel.bin.path(`${rootDir}/etc/conda/deactivate.d`)
|
|
143
|
+
for (const hookDir of [activateDir, deactivateDir]) {
|
|
144
|
+
for (const filename of LEGACY_SSL_CERT_DIR_HOOK_FILES) {
|
|
145
|
+
await fs.promises.rm(path.resolve(hookDir, filename), { force: true }).catch(() => {})
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
for (const [filename, content] of Object.entries(WINDOWS_OPENSSL_HOOKS.activate)) {
|
|
149
|
+
const hookPath = path.resolve(activateDir, filename)
|
|
150
|
+
const exists = await fs.promises.access(hookPath).then(() => true).catch(() => false)
|
|
151
|
+
if (exists) {
|
|
152
|
+
await fs.promises.writeFile(hookPath, content)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const [filename, content] of Object.entries(WINDOWS_OPENSSL_HOOKS.deactivate)) {
|
|
156
|
+
const hookPath = path.resolve(deactivateDir, filename)
|
|
157
|
+
const exists = await fs.promises.access(hookPath).then(() => true).catch(() => false)
|
|
158
|
+
if (exists) {
|
|
159
|
+
await fs.promises.writeFile(hookPath, content)
|
|
112
160
|
}
|
|
113
161
|
}
|
|
114
162
|
}
|
|
@@ -134,7 +182,7 @@ report_errors: false`)
|
|
|
134
182
|
await fs.promises.writeFile(this.kernel.path(`bin/${CONDA_ROOT_DIR}/conda-meta/pinned`), this.pinnedPackages())
|
|
135
183
|
await this.ensureCompatibilityAlias()
|
|
136
184
|
}
|
|
137
|
-
await this.
|
|
185
|
+
await this.ensureWindowsOpenSslHooks()
|
|
138
186
|
}
|
|
139
187
|
}
|
|
140
188
|
async check() {
|
|
@@ -282,7 +330,7 @@ report_errors: false`)
|
|
|
282
330
|
this.kernel.bin.path(CONDA_ROOT_DIR, "python3.exe"),
|
|
283
331
|
)
|
|
284
332
|
}
|
|
285
|
-
await this.
|
|
333
|
+
await this.ensureWindowsOpenSslHooks()
|
|
286
334
|
await this.ensureCompatibilityAlias()
|
|
287
335
|
ondata({ raw: `Install finished\r\n` })
|
|
288
336
|
await this.kernel.bin.rm(installer, ondata)
|
package/kernel/bin/index.js
CHANGED
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -6041,6 +6041,13 @@ class Server {
|
|
|
6041
6041
|
if (version === this.version.pinokiod) {
|
|
6042
6042
|
console.log("version up to date")
|
|
6043
6043
|
} else if (!(await fse.pathExists(path.resolve(home, "bin/miniforge/conda-meta")))) {
|
|
6044
|
+
// if miniconda => miniforge migration hasn't happened yet
|
|
6045
|
+
if (!(await fse.pathExists(path.resolve(home, "bin/miniconda/conda-meta")))) {
|
|
6046
|
+
// if miniconda folder does NOT exist (new user), set version
|
|
6047
|
+
// if miniconda folder exists (existing user), don't set version yet
|
|
6048
|
+
// => version only set after miniconda => miniforge migration has happened
|
|
6049
|
+
this.kernel.store.set("version", this.version.pinokiod)
|
|
6050
|
+
}
|
|
6044
6051
|
console.warn("[WARN] Managed home refresh deferred until Miniforge is installed")
|
|
6045
6052
|
} else {
|
|
6046
6053
|
// For every update, this gets triggered exactly once.
|
package/test/conda-bin.test.js
CHANGED
|
@@ -78,6 +78,88 @@ function createConda(kernel) {
|
|
|
78
78
|
return conda
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
const EXPECTED_WINDOWS_OPENSSL_HOOKS = {
|
|
82
|
+
[path.join('activate.d', 'openssl_activate-win.bat')]: [
|
|
83
|
+
'@echo off',
|
|
84
|
+
'if "%SSL_CERT_FILE%"=="" (',
|
|
85
|
+
' set "SSL_CERT_FILE=%CONDA_PREFIX%\\Library\\ssl\\cacert.pem"',
|
|
86
|
+
' set "__CONDA_OPENSSL_CERT_FILE_SET=1"',
|
|
87
|
+
')',
|
|
88
|
+
'',
|
|
89
|
+
].join('\r\n'),
|
|
90
|
+
[path.join('activate.d', 'openssl_activate-win.ps1')]: [
|
|
91
|
+
'if (-not $Env:SSL_CERT_FILE) {',
|
|
92
|
+
' $Env:SSL_CERT_FILE = "$Env:CONDA_PREFIX\\Library\\ssl\\cacert.pem"',
|
|
93
|
+
' $Env:__CONDA_OPENSSL_CERT_FILE_SET = "1"',
|
|
94
|
+
'}',
|
|
95
|
+
'',
|
|
96
|
+
].join('\r\n'),
|
|
97
|
+
[path.join('activate.d', 'openssl_activate-win.sh')]: [
|
|
98
|
+
'if [[ "${SSL_CERT_FILE:-}" == "" ]]; then',
|
|
99
|
+
' export SSL_CERT_FILE="${CONDA_PREFIX}\\\\Library\\\\ssl\\\\cacert.pem"',
|
|
100
|
+
' export __CONDA_OPENSSL_CERT_FILE_SET="1"',
|
|
101
|
+
'fi',
|
|
102
|
+
'',
|
|
103
|
+
].join('\n'),
|
|
104
|
+
[path.join('deactivate.d', 'openssl_deactivate-win.bat')]: [
|
|
105
|
+
'@echo off',
|
|
106
|
+
'if "%__CONDA_OPENSSL_CERT_FILE_SET%" == "1" (',
|
|
107
|
+
' set SSL_CERT_FILE=',
|
|
108
|
+
' set __CONDA_OPENSSL_CERT_FILE_SET=',
|
|
109
|
+
')',
|
|
110
|
+
'',
|
|
111
|
+
].join('\r\n'),
|
|
112
|
+
[path.join('deactivate.d', 'openssl_deactivate-win.ps1')]: [
|
|
113
|
+
'if ($Env:__CONDA_OPENSSL_CERT_FILE_SET -eq "1") {',
|
|
114
|
+
' Remove-Item -Path Env:\\SSL_CERT_FILE',
|
|
115
|
+
' Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_FILE_SET',
|
|
116
|
+
'}',
|
|
117
|
+
'',
|
|
118
|
+
].join('\r\n'),
|
|
119
|
+
[path.join('deactivate.d', 'openssl_deactivate-win.sh')]: [
|
|
120
|
+
'if [[ "${__CONDA_OPENSSL_CERT_FILE_SET:-}" == "1" ]]; then',
|
|
121
|
+
' unset SSL_CERT_FILE',
|
|
122
|
+
' unset __CONDA_OPENSSL_CERT_FILE_SET',
|
|
123
|
+
'fi',
|
|
124
|
+
'',
|
|
125
|
+
].join('\n'),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function seedWindowsOpenSslHooks(root, condaRootName) {
|
|
129
|
+
const condaHookRoot = path.join(root, 'bin', condaRootName, 'etc', 'conda')
|
|
130
|
+
for (const hookRelativePath of Object.keys(EXPECTED_WINDOWS_OPENSSL_HOOKS)) {
|
|
131
|
+
const hookPath = path.join(condaHookRoot, hookRelativePath)
|
|
132
|
+
await fs.mkdir(path.dirname(hookPath), { recursive: true })
|
|
133
|
+
await fs.writeFile(hookPath, 'upstream hook with SSL_CERT_DIR\n')
|
|
134
|
+
}
|
|
135
|
+
for (const hookDirName of ['activate.d', 'deactivate.d']) {
|
|
136
|
+
for (const filename of [
|
|
137
|
+
'zz_pinokio_unset_ssl_cert_dir-win.bat',
|
|
138
|
+
'zz_pinokio_unset_ssl_cert_dir-win.ps1',
|
|
139
|
+
'zz_pinokio_unset_ssl_cert_dir-win.sh',
|
|
140
|
+
]) {
|
|
141
|
+
await fs.writeFile(path.join(condaHookRoot, hookDirName, filename), 'legacy hook\n')
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function assertWindowsOpenSslHooksPatched(root, condaRootName) {
|
|
147
|
+
const condaHookRoot = path.join(root, 'bin', condaRootName, 'etc', 'conda')
|
|
148
|
+
for (const [hookRelativePath, expectedContent] of Object.entries(EXPECTED_WINDOWS_OPENSSL_HOOKS)) {
|
|
149
|
+
const hookPath = path.join(condaHookRoot, hookRelativePath)
|
|
150
|
+
assert.equal(await fs.readFile(hookPath, 'utf8'), expectedContent)
|
|
151
|
+
}
|
|
152
|
+
for (const hookDirName of ['activate.d', 'deactivate.d']) {
|
|
153
|
+
for (const filename of [
|
|
154
|
+
'zz_pinokio_unset_ssl_cert_dir-win.bat',
|
|
155
|
+
'zz_pinokio_unset_ssl_cert_dir-win.ps1',
|
|
156
|
+
'zz_pinokio_unset_ssl_cert_dir-win.sh',
|
|
157
|
+
]) {
|
|
158
|
+
assert.equal(await pathExists(path.join(condaHookRoot, hookDirName, filename)), false)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
81
163
|
test('Conda uses Miniforge assets and writes conda-forge-only config', async () => {
|
|
82
164
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-miniforge-config-'))
|
|
83
165
|
const conda = createConda(createKernel(root))
|
|
@@ -99,59 +181,26 @@ test('Conda uses Miniforge assets and writes conda-forge-only config', async ()
|
|
|
99
181
|
assert.equal(await pathExists(path.join(root, 'bin', 'miniforge')), false)
|
|
100
182
|
})
|
|
101
183
|
|
|
102
|
-
test('Conda init
|
|
103
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-
|
|
184
|
+
test('Conda init patches Windows OpenSSL hooks and removes legacy SSL_CERT_DIR hooks', async () => {
|
|
185
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-openssl-hooks-'))
|
|
104
186
|
await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
|
|
187
|
+
await seedWindowsOpenSslHooks(root, 'miniforge')
|
|
105
188
|
const conda = createConda(createKernel(root))
|
|
106
189
|
|
|
107
190
|
await conda.init()
|
|
108
191
|
|
|
109
|
-
|
|
110
|
-
path.join('activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat'),
|
|
111
|
-
path.join('activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.ps1'),
|
|
112
|
-
path.join('activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.sh'),
|
|
113
|
-
path.join('deactivate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat'),
|
|
114
|
-
path.join('deactivate.d', 'zz_pinokio_unset_ssl_cert_dir-win.ps1'),
|
|
115
|
-
path.join('deactivate.d', 'zz_pinokio_unset_ssl_cert_dir-win.sh'),
|
|
116
|
-
]
|
|
117
|
-
for (const hookRelativePath of hookRelativePaths) {
|
|
118
|
-
assert.equal(
|
|
119
|
-
await pathExists(path.join(root, 'bin', 'miniforge', 'etc', 'conda', hookRelativePath)),
|
|
120
|
-
true
|
|
121
|
-
)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const batHook = await fs.readFile(
|
|
125
|
-
path.join(root, 'bin', 'miniforge', 'etc', 'conda', 'activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat'),
|
|
126
|
-
'utf8'
|
|
127
|
-
)
|
|
128
|
-
assert.match(batHook, /set "SSL_CERT_DIR="/)
|
|
129
|
-
assert.match(batHook, /set "__CONDA_OPENSSL_CERT_DIR_SET="/)
|
|
130
|
-
assert.doesNotMatch(batHook, /SSL_CERT_FILE/)
|
|
192
|
+
await assertWindowsOpenSslHooksPatched(root, 'miniforge')
|
|
131
193
|
})
|
|
132
194
|
|
|
133
|
-
test('Conda init
|
|
134
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-legacy-
|
|
195
|
+
test('Conda init patches Windows OpenSSL hooks for legacy Miniconda roots', async () => {
|
|
196
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-legacy-openssl-hooks-'))
|
|
135
197
|
await fs.mkdir(path.join(root, 'bin', 'miniconda', 'conda-meta'), { recursive: true })
|
|
198
|
+
await seedWindowsOpenSslHooks(root, 'miniconda')
|
|
136
199
|
const conda = createConda(createKernel(root))
|
|
137
200
|
|
|
138
201
|
await conda.init()
|
|
139
202
|
|
|
140
|
-
|
|
141
|
-
root,
|
|
142
|
-
'bin',
|
|
143
|
-
'miniconda',
|
|
144
|
-
'etc',
|
|
145
|
-
'conda',
|
|
146
|
-
'deactivate.d',
|
|
147
|
-
'zz_pinokio_unset_ssl_cert_dir-win.bat'
|
|
148
|
-
)
|
|
149
|
-
assert.equal(await pathExists(batHookPath), true)
|
|
150
|
-
|
|
151
|
-
const batHook = await fs.readFile(batHookPath, 'utf8')
|
|
152
|
-
assert.match(batHook, /set "SSL_CERT_DIR="/)
|
|
153
|
-
assert.match(batHook, /set "__CONDA_OPENSSL_CERT_DIR_SET="/)
|
|
154
|
-
assert.doesNotMatch(batHook, /SSL_CERT_FILE/)
|
|
203
|
+
await assertWindowsOpenSslHooksPatched(root, 'miniconda')
|
|
155
204
|
})
|
|
156
205
|
|
|
157
206
|
test('Conda pins Python 3.10.20 consistently across platforms', async () => {
|