Skip to content

Commit

Permalink
Fix not preserving uid and/or gid (#35)
Browse files Browse the repository at this point in the history
* Fix not preserving uid and/or gid

Signed-off-by: Musaed Albrikan <[email protected]>

* Add generated build files

Signed-off-by: Musaed Albrikan <[email protected]>

* Use pnpm instead of npm to build

Signed-off-by: Musaed Albrikan <[email protected]>

---------

Signed-off-by: Musaed Albrikan <[email protected]>
  • Loading branch information
mabrikan authored Jun 10, 2024
1 parent 87e6a3b commit 1e9b89a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 5 deletions.
25 changes: 24 additions & 1 deletion dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions src/inject-cache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs/promises';
import path from 'path';
import { CacheOptions, Opts, getCacheMap, getMountArgsString, getTargetPath } from './opts.js';
import { CacheOptions, Opts, getCacheMap, getMountArgsString, getTargetPath, getUID, getGID } from './opts.js';
import { run } from './run.js';
import { notice } from '@actions/core';

Expand All @@ -19,13 +19,21 @@ async function injectCache(cacheSource: string, cacheOptions: CacheOptions, scra
const targetPath = getTargetPath(cacheOptions);
const mountArgs = getMountArgsString(cacheOptions);

// If UID OR GID are set, then add chown to restore files ownership.
let ownershipCommand = "";
const uid = getUID(cacheOptions);
const gid = getGID(cacheOptions);
if (uid !== "" || gid !== "") {
ownershipCommand = `&& chown -R ${uid}:${gid} ${targetPath}`
}

// Prepare Dancefile to Access Caches
const dancefileContent = `
FROM busybox:1
COPY buildstamp buildstamp
RUN --mount=${mountArgs} \
--mount=type=bind,source=.,target=/var/dance-cache \
cp -p -R /var/dance-cache/. ${targetPath} || true
cp -p -R /var/dance-cache/. ${targetPath} ${ownershipCommand} || true
`;
await fs.writeFile(path.join(scratchDir, 'Dancefile.inject'), dancefileContent);
console.log(dancefileContent);
Expand Down
28 changes: 28 additions & 0 deletions src/opts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,34 @@ export function getTargetPath(cacheOptions: CacheOptions): TargetPath {
}
}

export function getUID(cacheOptions: CacheOptions): string {
if (typeof cacheOptions === "string") {
// only the target path is provided
return "";
} else {
// object is provided
if ("uid" in cacheOptions && cacheOptions.uid !== undefined) {
return cacheOptions.uid.toString();
} else {
return "";
}
}
}

export function getGID(cacheOptions: CacheOptions): string {
if (typeof cacheOptions === "string") {
// only the target path is provided
return "";
} else {
// object is provided
if ("gid" in cacheOptions && cacheOptions.gid !== undefined) {
return cacheOptions.gid.toString();
} else {
return "";
}
}
}

/**
* Convert a cache options to a string that is passed to --mount=
* @param CacheOptions The cache options to convert to a string
Expand Down
40 changes: 39 additions & 1 deletion tests/opts.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from 'vitest'
import { getCacheMap, getTargetPath, getMountArgsString, parseOpts } from '../src/opts.js'
import { getCacheMap, getTargetPath, getMountArgsString, parseOpts, getUID, getGID } from '../src/opts.js'

test('parseOpts with no arguments', () => {
const opts = parseOpts([])
Expand Down Expand Up @@ -94,3 +94,41 @@ test('getMountArgsString with object', () => {
const mountString = getMountArgsString(cacheOptions)
expect(mountString).toBe('type=cache,target=targetPath,shared=true,id=1')
})

test('getUID with string', () => {
const cacheOptions = 'targetPath'
const uid = getUID(cacheOptions)
expect(uid).toBe('')
})


test('getUID with object without uid', () => {
const cacheOptions = { target: 'targetPath', shared: true, id: 1 }
const uid = getUID(cacheOptions)
expect(uid).toBe('')
})

test('getUID with object with uid', () => {
const cacheOptions = { target: 'targetPath', shared: true, id: 1, uid: 1000 }
const uid = getUID(cacheOptions)
expect(uid).toBe('1000')
})

test('getGID with string', () => {
const cacheOptions = 'targetPath'
const gid = getGID(cacheOptions)
expect(gid).toBe('')
})


test('getGID with object without gid', () => {
const cacheOptions = { target: 'targetPath', shared: true, id: 1 }
const gid = getGID(cacheOptions)
expect(gid).toBe('')
})

test('getGID with object with gid', () => {
const cacheOptions = { target: 'targetPath', shared: true, id: 1, gid: 1000 }
const gid = getGID(cacheOptions)
expect(gid).toBe('1000')
})

0 comments on commit 1e9b89a

Please sign in to comment.