Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,32 @@ describe('installOciPlugin — floating tags (RHDHBUGS-1077)', () => {
expect(result.pluginPath).toBeNull();
expect(calls.getDigest).toEqual([]);
});

it('re-installs rather than skipping when the configured pullPolicy is not a recognised value', async () => {
// `dynamic-plugins.yaml` is read with `parseYaml(...) as DynamicPluginsConfig`
// (installer.ts) — a type assertion, not a runtime check — so a typo like
// `pullPolicy: Never` reaches here as an unrecognised string. It must fall
// through to a re-install; silently skipping would strand the plugin at
// whatever version happened to be on disk.
const installed = await seedInstalled('digest-aaaa');
const tarball = await makeLayerTarball(PLUGIN_PATH, '{"name":"my-plugin"}');
const { cache, calls } = recordingImageCache({
digest: 'digest-aaaa',
tarball,
});

const result = await installOciPlugin(
ociPlugin({ pullPolicy: 'Never' as PullPolicy }),
destination,
cache,
installed,
);

expect(result.pluginPath).toBe(PLUGIN_PATH);
expect(calls.getTarball).toHaveLength(1);
// Never consults the registry for a digest it would not know how to act on.
expect(calls.getDigest).toEqual(['oci://registry.io/org/plugin:latest']);
});
});

describe('installOciPlugin — package spec handling', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ function splitOciPackage(
if (bang === -1) return null;
const imagePart = pkg.slice(0, bang);
const pluginPath = pkg.slice(bang + 1);
/* istanbul ignore next -- unreachable on the install path: OCI_REGEX rejects
a leading or trailing `!` (oci-key.test.ts `invalidCases`), and a package
with no `!` at all has one appended by the merger before it gets here
(merger.ts, `!plugin.package.includes('!')` and resolveInherit). Kept so
this function stays total if either changes. */
if (!imagePart || !pluginPath) return null;
return { imagePart, pluginPath };
}
Expand Down Expand Up @@ -137,13 +142,19 @@ async function isAlreadyInstalled(
return true;
}

// Not unreachable: `dynamic-plugins.yaml` is parsed with a type assertion,
// not a runtime check, so a typo'd `pullPolicy` arrives here as an
// unrecognised string and must fall through to a re-install.
if (pullPolicy !== PullPolicy.ALWAYS) return false;

const digestFile = path.join(destination, pathInstalled, IMAGE_HASH_FILE);
if (!(await fileExists(digestFile))) return false;

const localDigest = (await fs.readFile(digestFile, 'utf8')).trim();
const parts = splitOciPackage(pkg);
/* istanbul ignore next -- unreachable for the same reason as the guard in
splitOciPackage: every `pkg` that reaches here carries a `!<path>`, either
from the user or appended by the merger. */
if (!parts) return false;
const remoteDigest = await imageCache.getDigest(parts.imagePart);
if (localDigest !== remoteDigest) return false;
Expand Down
Loading