UNPKG

16.9 kBSource Map (JSON)View Raw
1{"version":3,"file":"vmdk-generate.js","names":["assert","_interopRequireWildcard","require","_zlib","_interopRequireDefault","_definitions","obj","__esModule","default","_getRequireWildcardCache","e","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","roundToSector","value","Math","ceil","SECTOR_SIZE","generateVmdkData","diskName","diskCapacityBytes","blockSizeBytes","blockGenerator","geometry","sectorsPerTrackCylinder","heads","cylinders","dataSize","cid","floor","random","pow","diskCapacitySectors","descriptor","utf8Descriptor","Buffer","from","descriptorSizeSectors","length","descriptorBuffer","alloc","copy","headerData","createStreamOptimizedHeader","parsedHeader","unpackHeader","buffer","grainSizeBytes","grainSizeSectors","Error","grainTableEntries","tableBuffer","streamPosition","directoryOffset","endMetadataLength","computeEndMetadataLength","metadataSize","track","equal","createEmptyMarker","type","buff","writeBigUInt64LE","BigInt","writeUInt32LE","createDirectoryBuffer","grainDirectoryEntries","tablePosition","OFFSET_SIZE","numGTEsPerGT","bufferIsBlank","b","createMarkedGrain","lbaBytes","strictEqual","markerOverHead","compressed","zlib","deflateSync","level","constants","Z_BEST_SPEED","outputBuffer","emitBlock","blockLbaBytes","grainCount","grainLbaBytes","tableIndex","grainData","slice","emitBlocks","grainSize","lba","block","padding","undefined","targetSize","remaining","size","fullBuffer","iterator","MARKER_GT","tableOffset","MARKER_GD","rDirectoryOffset","MARKER_FOOTER","footer","MARKER_EOS"],"sources":["../src/vmdk-generate.js"],"sourcesContent":["import * as assert from 'assert'\nimport zlib from 'zlib'\n\nimport {\n SECTOR_SIZE,\n createStreamOptimizedHeader,\n unpackHeader,\n MARKER_GT,\n MARKER_GD,\n MARKER_FOOTER,\n MARKER_EOS,\n} from './definitions'\n\nconst roundToSector = value => Math.ceil(value / SECTOR_SIZE) * SECTOR_SIZE\n\n/**\n * - block is an input bunch of bytes, VHD default size is 2MB\n * - grain is an output (VMDK) bunch of bytes, VMDK default is 64KB\n * expected ratio for default values is 16 VMDK grains for one VHD block\n * this function errors if blockSize < grainSize\n * The generated file is streamoptimized, compressed grains, tables at the end.\n * @param diskName\n * @param diskCapacityBytes\n * @param blockSizeBytes\n * @param blockGenerator async generator of {lba:Number, block:Buffer} objects.\n * @param geometry an object of shape {sectorsPerTrackCylinder,heads,cylinders}\n * @returns an Async generator of Buffers representing the VMDK file fragments\n */\nexport async function generateVmdkData(\n diskName,\n diskCapacityBytes,\n blockSizeBytes,\n blockGenerator,\n geometry = {\n sectorsPerTrackCylinder: 63,\n heads: 16,\n cylinders: 10402,\n },\n dataSize\n) {\n const cid = Math.floor(Math.random() * Math.pow(2, 32))\n const diskCapacitySectors = Math.ceil(diskCapacityBytes / SECTOR_SIZE)\n // Virtual Box can't parse indented descriptors\n const descriptor = `# Disk DescriptorFile\nversion=1\nCID=${cid}\nparentCID=ffffffff\ncreateType=\"streamOptimized\"\n# Extent description\nRW ${diskCapacitySectors} SPARSE \"${diskName}\"\n# The Disk Data Base\n#DDB\nddb.adapterType = \"ide\"\nddb.geometry.sectors = \"${geometry.sectorsPerTrackCylinder}\"\nddb.geometry.heads = \"${geometry.heads}\"\nddb.geometry.cylinders = \"${geometry.cylinders}\"\n`\n const utf8Descriptor = Buffer.from(descriptor, 'utf8')\n\n // virtual box add some additional properties to the descriptor like:\n // ddb.uuid.image=\"9afa1dd0-d966-4279-a762-b7fbb0136308\"\n // ddb.uuid.modification=\"cd9be63c-4953-44d0-8325-45635a9ca396\"\n // ddb.uuid.parent=\"00000000-0000-0000-0000-000000000000\"\n // ddb.uuid.parentmodification=\"00000000-0000-0000-0000-000000000000\"\n //\n // but does not ensure there is enough free room and overwrite the data (the grain directory), breaking the file\n //\n // adding 10 sectors of padding seems to be enough to work-around the issue\n const descriptorSizeSectors = Math.ceil(utf8Descriptor.length / SECTOR_SIZE) + 10\n const descriptorBuffer = Buffer.alloc(descriptorSizeSectors * SECTOR_SIZE)\n utf8Descriptor.copy(descriptorBuffer)\n const headerData = createStreamOptimizedHeader(diskCapacitySectors, descriptorSizeSectors)\n const parsedHeader = unpackHeader(headerData.buffer)\n const grainSizeBytes = parsedHeader.grainSizeSectors * SECTOR_SIZE\n if (blockSizeBytes % grainSizeBytes !== 0 || blockSizeBytes === 0) {\n throw new Error(\n `createReadableVmdkStream can only accept block size multiple of ${grainSizeBytes}, got ${blockSizeBytes}`\n )\n }\n\n const grainTableEntries = headerData.grainTableEntries\n const tableBuffer = Buffer.alloc(grainTableEntries * 4)\n\n let streamPosition = 0\n let directoryOffset = 0\n const endMetadataLength = computeEndMetadataLength()\n const metadataSize = headerData.buffer.length + descriptorBuffer.length + endMetadataLength\n\n function track(buffer) {\n assert.equal(streamPosition % SECTOR_SIZE, 0)\n if (buffer.length > 0) {\n streamPosition += buffer.length\n }\n return buffer\n }\n\n function createEmptyMarker(type) {\n const buff = Buffer.alloc(SECTOR_SIZE)\n buff.writeBigUInt64LE(BigInt(0), 0)\n buff.writeUInt32LE(0, 8)\n buff.writeUInt32LE(type, 12)\n return buff\n }\n\n function createDirectoryBuffer(grainDirectoryEntries, tablePosition) {\n const OFFSET_SIZE = 4\n directoryOffset = streamPosition\n const buff = Buffer.alloc(roundToSector(grainDirectoryEntries * OFFSET_SIZE))\n for (let i = 0; i < grainDirectoryEntries; i++) {\n buff.writeUInt32LE((tablePosition + i * parsedHeader.numGTEsPerGT * OFFSET_SIZE) / SECTOR_SIZE, i * OFFSET_SIZE)\n }\n return buff\n }\n\n function bufferIsBlank(buffer) {\n for (const b of buffer) {\n if (b !== 0) {\n return false\n }\n }\n return true\n }\n\n function createMarkedGrain(lbaBytes, buffer) {\n assert.strictEqual(buffer.length, grainSizeBytes)\n assert.strictEqual(lbaBytes % grainSizeBytes, 0)\n const markerOverHead = 12\n const compressed = zlib.deflateSync(buffer, { level: zlib.constants.Z_BEST_SPEED })\n const outputBuffer = Buffer.alloc(roundToSector(markerOverHead + compressed.length))\n compressed.copy(outputBuffer, markerOverHead)\n outputBuffer.writeBigUInt64LE(BigInt(lbaBytes / SECTOR_SIZE), 0)\n outputBuffer.writeUInt32LE(compressed.length, 8)\n return outputBuffer\n }\n\n async function* emitBlock(blockLbaBytes, buffer, grainSizeBytes) {\n assert.strictEqual(buffer.length % grainSizeBytes, 0)\n const grainCount = buffer.length / grainSizeBytes\n for (let i = 0; i < grainCount; i++) {\n const grainLbaBytes = blockLbaBytes + i * grainSizeBytes\n const tableIndex = grainLbaBytes / grainSizeBytes\n const grainData = buffer.slice(i * grainSizeBytes, (i + 1) * grainSizeBytes)\n if (!bufferIsBlank(grainData)) {\n tableBuffer.writeUInt32LE(streamPosition / SECTOR_SIZE, tableIndex * 4)\n yield track(createMarkedGrain(grainLbaBytes, grainData))\n }\n }\n }\n\n async function* emitBlocks(grainSize, blockGenerator) {\n for await (const b of blockGenerator) {\n yield* emitBlock(b.lba, b.block, grainSize)\n }\n }\n\n function computeEndMetadataLength() {\n return (\n SECTOR_SIZE + // MARKER_GT\n roundToSector(tableBuffer.length) +\n SECTOR_SIZE + // MARKER_GD\n roundToSector(headerData.grainDirectoryEntries * 4) +\n SECTOR_SIZE + // MARKER_GT\n roundToSector(tableBuffer.length) +\n SECTOR_SIZE + // MARKER_GD\n roundToSector(headerData.grainDirectoryEntries * 4) +\n SECTOR_SIZE + // MARKER_FOOTER\n SECTOR_SIZE + // stream optimizedheader\n SECTOR_SIZE // MARKER_EOS\n )\n }\n\n function* padding() {\n if (dataSize === undefined) {\n return\n }\n const targetSize = dataSize + metadataSize\n let remaining = targetSize - streamPosition - endMetadataLength\n\n if (remaining < 0) {\n throw new Error(`vmdk is bigger than precalculed size`)\n }\n const size = 1024 * 1024\n const fullBuffer = Buffer.alloc(size, 0)\n while (remaining > size) {\n yield track(fullBuffer)\n remaining -= size\n }\n yield track(Buffer.alloc(remaining))\n }\n\n async function* iterator() {\n yield track(headerData.buffer)\n yield track(descriptorBuffer)\n yield* emitBlocks(grainSizeBytes, blockGenerator)\n yield* padding()\n yield track(createEmptyMarker(MARKER_GT))\n let tableOffset = streamPosition\n // grain tables\n yield track(tableBuffer)\n // redundant grain directory\n // virtual box and esxi seems to prefer having both\n yield track(createEmptyMarker(MARKER_GD))\n yield track(createDirectoryBuffer(headerData.grainDirectoryEntries, tableOffset))\n const rDirectoryOffset = directoryOffset\n\n // grain tables (again)\n yield track(createEmptyMarker(MARKER_GT))\n tableOffset = streamPosition\n yield track(tableBuffer)\n // main grain directory (same data)\n yield track(createEmptyMarker(MARKER_GD))\n yield track(createDirectoryBuffer(headerData.grainDirectoryEntries, tableOffset))\n yield track(createEmptyMarker(MARKER_FOOTER))\n const footer = createStreamOptimizedHeader(\n diskCapacitySectors,\n descriptorSizeSectors,\n directoryOffset / SECTOR_SIZE,\n rDirectoryOffset / SECTOR_SIZE\n )\n yield track(footer.buffer)\n yield track(createEmptyMarker(MARKER_EOS))\n }\n return {\n iterator: iterator(),\n metadataSize,\n }\n}\n"],"mappings":"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"}
\No newline at end of file