Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion __tests__/oci/oci.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,43 @@
* limitations under the License.
*/

import {afterEach, describe, expect, test} from '@jest/globals';
import {afterEach, describe, expect, jest, test} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import path from 'path';
import * as rimraf from 'rimraf';
import osm = require('os');

import {OCI} from '../../src/oci/oci';

import {Platform} from '../../src/types/oci/descriptor';

const fixturesDir = path.join(__dirname, '..', '.fixtures');
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'oci-oci-'));

afterEach(function () {
rimraf.sync(tmpDir);
});

describe('defaultPlatform', () => {
test.each([
['win32', 'x64', {architecture: 'amd64', os: 'windows'}],
['win32', 'arm64', {architecture: 'arm64', os: 'windows'}],
['darwin', 'x64', {architecture: 'amd64', os: 'darwin'}],
['darwin', 'arm64', {architecture: 'arm64', os: 'darwin'}],
['linux', 'ia32', {architecture: '386', os: 'linux'}],
['linux', 'x64', {architecture: 'amd64', os: 'linux'}],
['linux', 'arm64', {architecture: 'arm64', os: 'linux'}],
['linux', 'ppc64', {architecture: 'ppc64le', os: 'linux'}],
['linux', 's390x', {architecture: 's390x', os: 'linux'}]
])('default platform for %s/%s', async (os: string, arch: string, expected: Platform) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const res = OCI.defaultPlatform();
expect(res).toEqual(expected);
});
});

describe('loadArchive', () => {
// prettier-ignore
test.each(fs.readdirSync(path.join(fixturesDir, 'oci-archive')).filter(file => {
Expand Down
48 changes: 48 additions & 0 deletions src/oci/oci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,67 @@
* limitations under the License.
*/
import fs from 'fs';
import os from 'os';
import gunzip from 'gunzip-maybe';
import * as path from 'path';
import {Readable} from 'stream';
import * as tar from 'tar-stream';

import {Archive, LoadArchiveOpts} from '../types/oci/oci';
import {Index} from '../types/oci';
import {Platform} from '../types/oci/descriptor';
import {Manifest} from '../types/oci/manifest';
import {Image} from '../types/oci/config';
import {IMAGE_BLOBS_DIR_V1, IMAGE_INDEX_FILE_V1, IMAGE_LAYOUT_FILE_V1, ImageLayout} from '../types/oci/layout';
import {MEDIATYPE_IMAGE_INDEX_V1, MEDIATYPE_IMAGE_MANIFEST_V1} from '../types/oci/mediatype';

export class OCI {
public static defaultPlatform(): Platform {
const nodePlatform = os.platform();
const nodeArch = os.arch();

const goosMap: Record<string, string> = {
win32: 'windows',
sunos: 'solaris'
// others (linux, darwin, freebsd, openbsd, netbsd, aix, android) match Go already
};

const goArchMap: Record<string, string> = {
x64: 'amd64',
ia32: '386',
arm: 'arm',
arm64: 'arm64',
ppc64: 'ppc64le',
s390x: 's390x',
riscv64: 'riscv64',
loong64: 'loong64',
mips: 'mips',
mipsel: 'mipsle',
mips64: 'mips64',
mips64el: 'mips64le'
};

const goos = goosMap[nodePlatform] ?? nodePlatform;
const goarch = goArchMap[nodeArch] ?? nodeArch;

let variant: string | undefined;
if (goarch === 'arm') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const armVersionRaw = (process.config.variables as any)?.arm_version;
const armVersion = Number(armVersionRaw);
// Go only recognizes v5/v6/v7 for GOARM. Do not emit v8+ (that would be arm64).
if ([5, 6, 7].includes(armVersion)) {
variant = `v${armVersion}`;
}
}

return {
architecture: goarch,
os: goos,
variant: variant
};
}

public static loadArchive(opts: LoadArchiveOpts): Promise<Archive> {
return new Promise<Archive>((resolve, reject) => {
const tarex: tar.Extract = tar.extract();
Expand Down
Loading