|
1 | 1 | import os from 'node:os'
|
2 | 2 | import assert from 'node:assert'
|
3 | 3 | import { join } from 'node:path'
|
4 |
| -import { mkdir, chmod, rm, readFile, writeFile, stat } from 'node:fs/promises' |
5 |
| -import { fetch, Headers } from 'undici' |
| 4 | +import { mkdir, chmod } from 'node:fs/promises' |
| 5 | +import { fetch } from 'undici' |
6 | 6 | import { pipeline } from 'node:stream/promises'
|
7 | 7 | import unzip from 'unzip-stream'
|
8 | 8 | import { createWriteStream } from 'node:fs'
|
9 | 9 | import { moduleBinaries } from './paths.js'
|
10 |
| -import * as Name from 'w3name' |
11 |
| -import { CarReader } from '@ipld/car' |
12 |
| -import { validateBlock } from '@web3-storage/car-block-validator' |
13 |
| -import { recursive as exporter } from 'ipfs-unixfs-exporter' |
14 | 10 | import * as tar from 'tar'
|
15 |
| -import { reportW3NameError } from './telemetry.js' |
16 | 11 |
|
17 | 12 | /** @typedef {import('unzip-stream').UnzipStreamEntry} UnzipStreamEntry */
|
18 | 13 |
|
19 | 14 | const { GITHUB_TOKEN } = process.env
|
20 | 15 | const authorization = GITHUB_TOKEN ? `Bearer ${GITHUB_TOKEN}` : undefined
|
21 | 16 |
|
22 |
| -const gateways = [ |
23 |
| - 'w3s.link', |
24 |
| - 'cf-ipfs.com', |
25 |
| - 'dweb.link' |
26 |
| -] |
27 |
| - |
28 | 17 | export const getBinaryModuleExecutable = ({
|
29 | 18 | module,
|
30 | 19 | executable
|
@@ -104,157 +93,3 @@ export const installBinaryModule = async ({
|
104 | 93 | }
|
105 | 94 | console.log(`[${module}] ✓ ${outFile}`)
|
106 | 95 | }
|
107 |
| - |
108 |
| -async function getLatestCID (ipnsKey) { |
109 |
| - const name = Name.parse(ipnsKey) |
110 |
| - let revision |
111 |
| - try { |
112 |
| - revision = await Name.resolve(name) |
113 |
| - } catch (err) { |
114 |
| - reportW3NameError() |
115 |
| - // These errors aren't actionable |
116 |
| - err.reportToSentry = false |
117 |
| - throw err |
118 |
| - } |
119 |
| - // /ipfs/:cid |
120 |
| - return revision.value.split('/').pop() |
121 |
| -} |
122 |
| - |
123 |
| -async function getLastSeenModuleCID ({ module, subnetVersionsDir }) { |
124 |
| - try { |
125 |
| - return await readFile(join(subnetVersionsDir, module), 'utf-8') |
126 |
| - } catch (err) { |
127 |
| - if (err.code !== 'ENOENT') { |
128 |
| - throw err |
129 |
| - } |
130 |
| - } |
131 |
| - return undefined |
132 |
| -} |
133 |
| - |
134 |
| -async function setLastSeenModuleCID ({ module, cid, subnetVersionsDir }) { |
135 |
| - await mkdir(subnetVersionsDir, { recursive: true }) |
136 |
| - await writeFile(join(subnetVersionsDir, module), cid) |
137 |
| -} |
138 |
| - |
139 |
| -export async function updateSourceFiles ({ |
140 |
| - module, |
141 |
| - ipnsKey, |
142 |
| - subnetVersionsDir, |
143 |
| - subnetSourcesDir, |
144 |
| - noCache |
145 |
| -}) { |
146 |
| - await mkdir(subnetSourcesDir, { recursive: true }) |
147 |
| - const outDir = join(subnetSourcesDir, module) |
148 |
| - |
149 |
| - const lastSeenCID = await getLastSeenModuleCID({ module, subnetVersionsDir }) |
150 |
| - if (lastSeenCID !== undefined) { |
151 |
| - // Use `console.error` because with `--json` stdout needs to be JSON only |
152 |
| - console.error(`[${module}] ⇣ checking for updates`) |
153 |
| - } |
154 |
| - |
155 |
| - const cid = await getLatestCID(ipnsKey) |
156 |
| - const isUpdate = lastSeenCID !== cid |
157 |
| - if (!isUpdate) { |
158 |
| - try { |
159 |
| - await stat(join(outDir, 'main.js')) |
160 |
| - console.error(`[${module}] ✓ no update available`) |
161 |
| - return false |
162 |
| - } catch (err) { |
163 |
| - console.error(`[${module}] Cannot find sources on disk`) |
164 |
| - } |
165 |
| - } |
166 |
| - |
167 |
| - let res |
168 |
| - for (const gateway of gateways) { |
169 |
| - try { |
170 |
| - const url = `https://${cid}.ipfs.${gateway}?format=car` |
171 |
| - console.error(`[${module}] ⇣ downloading source files via ${url}`) |
172 |
| - const headers = new Headers() |
173 |
| - if (noCache) headers.append('Cache-Control', 'no-cache') |
174 |
| - res = await fetch(url, { |
175 |
| - signal: AbortSignal.timeout(10_000), |
176 |
| - headers |
177 |
| - }) |
178 |
| - |
179 |
| - if (res.status >= 300) { |
180 |
| - throw new Error( |
181 |
| - `[${module}] Cannot fetch ${module} archive for ${cid}: ${res.status}\n` + |
182 |
| - await res.text() |
183 |
| - ) |
184 |
| - } |
185 |
| - |
186 |
| - if (!res.body) { |
187 |
| - throw new Error( |
188 |
| - `[${module}] Cannot fetch ${module} archive for ${cid}: no response body` |
189 |
| - ) |
190 |
| - } |
191 |
| - break |
192 |
| - } catch (err) { |
193 |
| - if (gateway === gateways[gateways.length - 1]) { |
194 |
| - throw new Error( |
195 |
| - `[${module}] Can't download module sources from any gateway`, |
196 |
| - { cause: err } |
197 |
| - ) |
198 |
| - } else { |
199 |
| - console.error(err) |
200 |
| - } |
201 |
| - } |
202 |
| - } |
203 |
| - |
204 |
| - const tarExtractWarnings = [] |
205 |
| - const tarExtractEntries = [] |
206 |
| - try { |
207 |
| - const reader = await CarReader.fromIterable(res.body) |
208 |
| - const entries = exporter(cid, { |
209 |
| - async get (blockCid) { |
210 |
| - const block = await reader.get(blockCid) |
211 |
| - try { |
212 |
| - await validateBlock(block) |
213 |
| - } catch (err) { |
214 |
| - throw new Error(`Invalid block ${blockCid} of root ${cid}`, { |
215 |
| - cause: err |
216 |
| - }) |
217 |
| - } |
218 |
| - return block.bytes |
219 |
| - } |
220 |
| - }) |
221 |
| - const { value: entry } = await entries.next() |
222 |
| - assert(entry, `No entries in ${module} archive`) |
223 |
| - // Depending on size, entries might be packaged as `file` or `raw` |
224 |
| - // https://github.com/web3-storage/w3up/blob/e8bffe2ee0d3a59a977d2c4b7efe425699424e19/packages/upload-client/src/unixfs.js#L11 |
225 |
| - if (entry.type === 'file' || entry.type === 'raw') { |
226 |
| - await mkdir(outDir, { recursive: true }) |
227 |
| - // `{ strip: 1 }` tells tar to remove the top-level directory (e.g. `mod-peer-checker-v1.0.0`) |
228 |
| - await pipeline( |
229 |
| - /** @type {any} */(entry.content()), |
230 |
| - /** @type {any} */(tar.x({ |
231 |
| - strip: 1, |
232 |
| - C: outDir, |
233 |
| - onwarn (code, message, data) { |
234 |
| - tarExtractWarnings.push({ code, message, data }) |
235 |
| - }, |
236 |
| - onReadEntry (entry) { |
237 |
| - tarExtractEntries.push(entry.path) |
238 |
| - } |
239 |
| - })) |
240 |
| - ) |
241 |
| - await stat(join(outDir, 'main.js')) |
242 |
| - } |
243 |
| - } catch (err) { |
244 |
| - try { |
245 |
| - await rm(outDir, { recursive: true }) |
246 |
| - } catch { |
247 |
| - if (err.code !== 'ENOENT') { |
248 |
| - throw err |
249 |
| - } |
250 |
| - } |
251 |
| - err.tarExtractWarnings = tarExtractWarnings |
252 |
| - err.tarExtractEntries = tarExtractEntries |
253 |
| - throw err |
254 |
| - } |
255 |
| - |
256 |
| - await setLastSeenModuleCID({ module, cid, subnetVersionsDir }) |
257 |
| - console.error(`[${module}] ✓ ${outDir}`) |
258 |
| - |
259 |
| - return isUpdate |
260 |
| -} |
0 commit comments