UNPKG

26.7 kBSource Map (JSON)View Raw
1{"version":3,"file":"ova-read.js","names":["_assert","_interopRequireDefault","require","_find","_forEach","_pako","_sum","_xml2js","_interopRequireWildcard","_","_util","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","obj","MEMORY_UNIT_TO_FACTOR","k","m","g","RESOURCE_TYPE_TO_HANDLER","data","VirtualQuantity","nCpus","AllocationUnits","unit","quantity","memory","allocationUnitsToFactor","networks","AutomaticAllocation","enabled","Connection","name","push","disks","Address","address","AddressOnParent","position","Description","description","ElementName","Caption","caption","HostResource","resource","diskId","match","disk","undefined","parsed","replace","length","substring","split","fromEntries","map","couple","target","descriptionLabel","nameLabel","console","error","parseTarHeader","header","stringDeserializer","fileName","slice","sizeBuffer","fileSize","Uint8Array","byte","parseInt","ParsableFile","start","end","read","exports","ensureArray","value","Array","isArray","intValue","Math","pow","charAt","toLowerCase","cleanDisks","usedPositions","Set","nextPosition","keys","warn","add","parseOVF","fileFragment","xmlString","Promise","resolve","reject","xml2js","parseString","mergeAttrs","explicitArray","tagNameProcessors","processors","stripPrefix","attrNameProcessors","err","res","Envelope","DiskSection","Disk","References","File","files","VirtualSystem","system","hardware","VirtualHardwareSection","System","VirtualSystemIdentifier","AnnotationSection","Annotation","OperatingSystemSection","forEach","file","find","id","fileRef","capacityAllocationUnits","capacity","path","href","compression","handleItem","item","handler","ResourceType","Item","StorageItem","EthernetPortItem","GZIP_CHUNK_SIZE","parseGzipFromEnd","fileSlice","l","chunks","savedSize","currentDeflatedPos","inflate","pako","Inflate","compressed","Z_SYNC_FLUSH","chunk","result","pos","buffer","shift","resultBuffer","sum","c","index","parseOVAFile","parsableFile","skipVmdk","offset","HEADER_SIZE","tables","startsWith","endsWith","readFile","suppressUnhandledRejection","readVmdkGrainTable","forwardsInflater","parseGzipFromStart","resultStart","strm","total_out","isLast","total_in","assert","strictEqual","byteLength","ceil"],"sources":["../src/ova-read.js"],"sourcesContent":["import assert from 'assert'\nimport find from 'lodash/find'\nimport forEach from 'lodash/forEach'\nimport pako from 'pako'\nimport sum from 'lodash/sum'\nimport xml2js, { processors } from 'xml2js'\n\nimport { readVmdkGrainTable } from '.'\nimport { suppressUnhandledRejection } from './util'\n\n/********\n *\n * THIS FILE HAS TO WORK IN BOTH THE BROWSER AND NODE\n *\n ********/\n\n// See: http://opennodecloud.com/howto/2013/12/25/howto-ON-ovf-reference.html\n// See: http://www.dmtf.org/sites/default/files/standards/documents/DSP0243_1.0.0.pdf\n// See: http://www.dmtf.org/sites/default/files/standards/documents/DSP0243_2.1.0.pdf\n\nconst MEMORY_UNIT_TO_FACTOR = {\n k: 1024,\n m: 1048576,\n g: 1073741824,\n t: 1099511627776,\n}\nconst RESOURCE_TYPE_TO_HANDLER = {\n // CPU.\n 3: (data, { VirtualQuantity: nCpus }) => {\n data.nCpus = +nCpus\n },\n // RAM.\n 4: (data, { AllocationUnits: unit, VirtualQuantity: quantity }) => {\n data.memory = quantity * allocationUnitsToFactor(unit)\n },\n // Network.\n 10: ({ networks }, { AutomaticAllocation: enabled, Connection: name }) => {\n if (enabled) {\n networks.push(name)\n }\n },\n // Disk.\n 17: (\n { disks },\n {\n Address: address,\n AddressOnParent: position,\n Description: description = 'No description',\n ElementName: name,\n // OVA 2.0 uses caption\n Caption: caption = name,\n HostResource: resource,\n }\n ) => {\n const diskId = resource.match(/^(?:ovf:)?\\/disk\\/(.+)$/)\n const disk = diskId && disks[diskId[1]]\n if (position === undefined && address !== undefined) {\n // remove blanks\n let parsed = address.replace(/\\s+/g, '')\n // expecting \"{type=drive,bus=0,controller=0,target=0,unit=0}\"\n if (parsed[0] === '{' && parsed[parsed.length - 1] === '}') {\n parsed = parsed.substring(1, parsed.length - 1)\n // \"type=drive,bus=0,controller=0,target=0,unit=0\"\n parsed = parsed.split(',')\n // [\"type=drive\", \"bus=0\", \"controller=0\", \"target=0\", \"unit=0\"]\n parsed = Object.fromEntries(parsed.map(couple => couple.split('=')))\n // {type:\"drive\", bus:\"0\", controller:\"0\", target:\"0\",unit:\"0\"]\n // 'target' seems to be the field we want\n // https://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.ldva/ldva_r_XML_addressHostdev.html\n if ('target' in parsed) {\n position = +parsed.target\n }\n }\n }\n if (position === undefined) {\n position = 0\n }\n if (disk) {\n disk.descriptionLabel = description\n disk.nameLabel = caption\n disk.position = +position\n } else {\n // TODO: Log error in U.I.\n console.error(`No disk found: '${diskId}'.`)\n }\n },\n}\n\nfunction parseTarHeader(header, stringDeserializer) {\n const fileName = stringDeserializer(header.slice(0, 100), 'ascii').split('\\0')[0]\n if (fileName.length === 0) {\n return null\n }\n const sizeBuffer = header.slice(124, 124 + 12)\n // size encoding: https://codeistry.wordpress.com/2014/08/14/how-to-parse-a-tar-file/\n let fileSize = 0\n // If the leading byte is 0x80 (128), the non-leading bytes of the field are concatenated in big-endian order,\n // with the result being a positive number expressed in binary form.\n //\n // Source: https://www.gnu.org/software/tar/manual/html_node/Extensions.html\n if (new Uint8Array(sizeBuffer)[0] === 128) {\n for (const byte of new Uint8Array(sizeBuffer.slice(1))) {\n fileSize *= 256\n fileSize += byte\n }\n } else {\n fileSize = parseInt(stringDeserializer(sizeBuffer.slice(0, 11), 'ascii'), 8)\n }\n\n return { fileName, fileSize }\n}\n\nexport class ParsableFile {\n /** returns a ParsableFile */\n slice(start, end) {}\n\n /** reads the fragment, returns an ArrayBuffer */\n async read() {}\n}\n\nexport const ensureArray = value => {\n if (value === undefined) {\n return []\n }\n\n return Array.isArray(value) ? value : [value]\n}\n\nconst allocationUnitsToFactor = unit => {\n const intValue = unit.match(/\\^([0-9]+)$/)\n return intValue != null ? Math.pow(2, intValue[1]) : MEMORY_UNIT_TO_FACTOR[unit.charAt(0).toLowerCase()]\n}\n\nconst cleanDisks = disks => {\n const usedPositions = new Set()\n let nextPosition = Object.keys(disks).length\n for (const diskId in disks) {\n let position = disks[diskId].position\n if (position == null) {\n // TODO: Log error in U.I.\n console.error(`No position specified for '${diskId}'.`)\n delete disks[diskId]\n } else {\n if (usedPositions.has(position)) {\n console.warn(\n `There is at least two disks with position ${position}, we're changing the second one to ${nextPosition}`\n )\n disks[diskId].position = position = nextPosition\n nextPosition++\n }\n usedPositions.add(position)\n }\n }\n}\n\nexport async function parseOVF(fileFragment, stringDeserializer) {\n const xmlString = stringDeserializer(await fileFragment.read(), 'utf-8')\n return new Promise((resolve, reject) =>\n xml2js.parseString(\n xmlString,\n {\n mergeAttrs: true,\n explicitArray: false,\n tagNameProcessors: [processors.stripPrefix],\n attrNameProcessors: [processors.stripPrefix],\n },\n (err, res) => {\n if (err) {\n reject(err)\n return\n }\n\n const {\n Envelope: {\n DiskSection: { Disk: disks },\n References: { File: files },\n VirtualSystem: system,\n },\n } = res\n\n const data = {\n disks: {},\n networks: [],\n }\n const hardware = system.VirtualHardwareSection\n\n // Get VM name/description.\n data.nameLabel = hardware.System.VirtualSystemIdentifier\n data.descriptionLabel =\n (system.AnnotationSection && system.AnnotationSection.Annotation) ||\n (system.OperatingSystemSection && system.OperatingSystemSection.Description)\n\n // Get disks.\n forEach(ensureArray(disks), disk => {\n const file = find(ensureArray(files), file => file.id === disk.fileRef)\n const unit = disk.capacityAllocationUnits\n\n data.disks[disk.diskId] = {\n capacity: disk.capacity * ((unit && allocationUnitsToFactor(unit)) || 1),\n path: file && file.href,\n compression: file && file.compression,\n }\n })\n // Get hardware info: CPU, RAM, disks, networks...\n const handleItem = item => {\n const handler = RESOURCE_TYPE_TO_HANDLER[item.ResourceType]\n if (!handler) {\n return\n }\n handler(data, item)\n }\n forEach(ensureArray(hardware.Item), handleItem)\n forEach(ensureArray(hardware.StorageItem), handleItem)\n forEach(ensureArray(hardware.EthernetPortItem), handleItem)\n // Remove disks which not have a position.\n // (i.e. no info in hardware.Item section.)\n cleanDisks(data.disks)\n resolve(data)\n }\n )\n )\n}\n\nconst GZIP_CHUNK_SIZE = 4 * 1024 * 1024\n\n// start and end are negative numbers\n// used with streamOptimized format where only the footer has the directory address filled\nasync function parseGzipFromEnd(start, end, fileSlice, header) {\n const l = end - start\n const chunks = []\n let savedSize = 0\n let currentDeflatedPos = 0\n const inflate = new pako.Inflate()\n while (currentDeflatedPos < header.fileSize) {\n const slice = fileSlice.slice(currentDeflatedPos, currentDeflatedPos + GZIP_CHUNK_SIZE)\n const compressed = await slice.read()\n inflate.push(compressed, pako.Z_SYNC_FLUSH)\n const chunk = inflate.result.slice()\n chunks.push({ pos: currentDeflatedPos, buffer: chunk })\n savedSize += chunk.length\n if (savedSize - chunks[0].buffer.length >= l) {\n savedSize -= chunks[0].buffer.length\n chunks.shift()\n }\n currentDeflatedPos += GZIP_CHUNK_SIZE\n }\n let resultBuffer = new Uint8Array(sum(chunks.map(c => c.buffer.length)))\n let index = 0\n chunks.forEach(c => {\n resultBuffer.set(c.buffer, index)\n index += c.buffer.length\n })\n resultBuffer = resultBuffer.slice(start, end)\n return resultBuffer.buffer\n}\n\n/**\n *\n * @param parsableFile: ParsableFile\n * @param stringDeserializer function (ArrayBuffer, encoding) => String\n * @param skipVmdk if true avoid parsing the VMDK file tables\n * @returns {Promise<{tables: {}}>}\n */\nexport async function parseOVAFile(parsableFile, stringDeserializer, skipVmdk = false) {\n let offset = 0\n const HEADER_SIZE = 512\n let data = { tables: {} }\n while (true) {\n const header = parseTarHeader(await parsableFile.slice(offset, offset + HEADER_SIZE).read(), stringDeserializer)\n offset += HEADER_SIZE\n if (header === null) {\n break\n }\n const fileSlice = parsableFile.slice(offset, offset + header.fileSize)\n fileSlice.fileName = header.fileName\n if (!(header.fileName.startsWith('PaxHeader/') || header.fileName.startsWith('.'))) {\n if (header.fileName.toLowerCase().endsWith('.ovf')) {\n const res = await parseOVF(fileSlice, stringDeserializer)\n data = { ...data, ...res }\n }\n if (!skipVmdk && header.fileName.toLowerCase().endsWith('.vmdk')) {\n const readFile = async (start, end) => fileSlice.slice(start, end).read()\n readFile.fileName = header.fileName\n data.tables[header.fileName] = suppressUnhandledRejection(readVmdkGrainTable(readFile))\n }\n }\n if (!skipVmdk && header.fileName.toLowerCase().endsWith('.vmdk.gz')) {\n let forwardsInflater = new pako.Inflate()\n\n const readFile = async (start, end) => {\n // if next read is further down the stream than previous read, re-uses the previous zstream\n async function parseGzipFromStart(start, end, fileSlice) {\n const chunks = []\n const resultStart = () => forwardsInflater.strm.total_out - forwardsInflater.result.length\n if (forwardsInflater.result != null && start < resultStart()) {\n // the block we are reading starts before the last decompressed chunk, reset stream\n forwardsInflater = new pako.Inflate()\n }\n let isLast = false\n while (true) {\n if (forwardsInflater.strm.total_out > start) {\n let chunk = forwardsInflater.result\n if (resultStart() < start) {\n chunk = chunk.slice(start - resultStart())\n }\n if (forwardsInflater.strm.total_out > end) {\n chunk = chunk.slice(0, -(forwardsInflater.strm.total_out - end))\n isLast = true\n }\n chunks.push(chunk)\n }\n if (isLast) {\n // don't move the stream forwards if we took our last chunk\n // gives the next read operation an opportunity to read from the same position\n break\n }\n const slice = fileSlice.slice(\n forwardsInflater.strm.total_in,\n forwardsInflater.strm.total_in + GZIP_CHUNK_SIZE\n )\n forwardsInflater.push(await slice.read(), pako.Z_SYNC_FLUSH)\n }\n const resultBuffer = new Uint8Array(sum(chunks.map(c => c.length)))\n let index = 0\n chunks.forEach(c => {\n resultBuffer.set(c, index)\n index += c.length\n })\n assert.strictEqual(resultBuffer.buffer.byteLength, end - start)\n return resultBuffer.buffer\n }\n\n if (start === end) {\n return new Uint8Array(0)\n }\n if (start >= 0 && end >= 0) {\n return parseGzipFromStart(start, end, fileSlice)\n } else if (start < 0 && end < 0) {\n return parseGzipFromEnd(start, end, fileSlice, header)\n }\n }\n readFile.fileName = header.fileName\n data.tables[header.fileName] = suppressUnhandledRejection(readVmdkGrainTable(readFile))\n }\n offset += Math.ceil(header.fileSize / 512) * 512\n }\n return data\n}\n"],"mappings":"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"}
\No newline at end of file