UNPKG

etcher-sdk

Version:
127 lines 4.21 kB
"use strict"; /* * Copyright 2018 balena.io * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.freeSpace = exports.withTmpFile = exports.tmpFile = exports.cleanupTmpFiles = void 0; const check_disk_space_1 = require("check-disk-space"); const crypto_1 = require("crypto"); const fs_1 = require("fs"); const os_1 = require("os"); const path_1 = require("path"); const TMP_RANDOM_BYTES = 6; const TMP_DIR = (0, path_1.join)((0, os_1.tmpdir)(), 'etcher'); const TRIES = 5; function randomFilePath(prefix, postfix) { return (0, path_1.join)(TMP_DIR, `${prefix}${(0, crypto_1.randomBytes)(TMP_RANDOM_BYTES).toString('hex')}${postfix}`); } async function cleanupTmpFiles(olderThan = Date.now(), prefix = '') { let dirents = []; try { dirents = await fs_1.promises.readdir(TMP_DIR, { withFileTypes: true }); } catch (_a) { return; } for (const dirent of dirents) { if (dirent.isFile()) { if (dirent.name.startsWith(prefix)) { const filename = (0, path_1.join)(TMP_DIR, dirent.name); try { const stats = await fs_1.promises.stat(filename); if (stats.ctime.getTime() <= olderThan) { await fs_1.promises.unlink(filename); } } catch (_b) { // noop } } } } } exports.cleanupTmpFiles = cleanupTmpFiles; async function createTmpRoot() { try { await fs_1.promises.mkdir(TMP_DIR, { recursive: true }); } catch (error) { // the 'recursive' option is only supported on node >= 10.12.0 if (error.code === 'EEXIST' && !(await fs_1.promises.stat(TMP_DIR)).isDirectory()) { await fs_1.promises.unlink(TMP_DIR); await fs_1.promises.mkdir(TMP_DIR, { recursive: true }); } } } async function tmpFile({ keepOpen = true, prefix = 'tmp-', postfix = '.tmp', }) { await createTmpRoot(); let fileHandle; let path; let ok = false; for (let i = 0; i < TRIES; i++) { path = randomFilePath(prefix, postfix); try { fileHandle = await fs_1.promises.open(path, 'wx+'); ok = true; break; } catch (error) { if (error.code !== 'EEXIST') { throw error; } } } if (!ok) { throw new Error(`Could not generate a temporary filename in ${TRIES} tries`); } if (!keepOpen && fileHandle !== undefined) { await fileHandle.close(); fileHandle = undefined; } return { fileHandle, path: path }; } exports.tmpFile = tmpFile; async function withTmpFile(options, fn) { const result = await tmpFile(options); try { return await fn(result); } finally { if (options.keepOpen && result.fileHandle !== undefined) { await result.fileHandle.close(); } try { await fs_1.promises.unlink(result.path); } catch (error) { // The file might already have been deleted by cleanupTmpFiles if (error.code !== 'ENOENT') { throw error; // eslint-disable-line no-unsafe-finally } } } } exports.withTmpFile = withTmpFile; async function freeSpace() { try { return (await (0, check_disk_space_1.default)(TMP_DIR)).free; } catch (error) { console.warn(`Could not check free disk space in "${TMP_DIR}": ${error}`); return 0; } } exports.freeSpace = freeSpace; //# sourceMappingURL=tmp.js.map