Skip to content

Commit c714ec7

Browse files
committed
fix: remove backup option to pull oci archive
Skopeo is capable of pulling an OCI image and it doesn't need a backup to pull an OCI archive. If the Docker archive pulling fails for some reason, the OCI archive pulling won't be able to succeed either. This backup option was introduced by mistake thinking that skopeo cannot handle certain images as Docker archives. The underlying problem was that the image itself was not OCI compliant and couldn't be pulled, so OCI archive pulling wouldn't have helped.
1 parent e482c1f commit c714ec7

File tree

7 files changed

+58
-80
lines changed

7 files changed

+58
-80
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"needle": "^3.0.0",
4848
"sleep-promise": "^9.1.0",
4949
"snyk-config": "5.0.0",
50-
"snyk-docker-plugin": "^4.33.2",
50+
"snyk-docker-plugin": "^4.34.2",
5151
"source-map-support": "^0.5.21",
5252
"tunnel": "0.0.6",
5353
"typescript": "^4.5.2",

src/scanner/images/index.ts

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { DepGraph, legacy } from '@snyk/dep-graph';
44

55
import { logger } from '../../common/logger';
66
import { pull as skopeoCopy, getDestinationForImage } from './skopeo';
7-
import { IPullableImage, IScanImage, SkopeoRepositoryType } from './types';
7+
import { IPullableImage, IScanImage } from './types';
88
import { IScanResult } from '../types';
99
import {
1010
buildDockerPropertiesOnDepTree,
@@ -22,23 +22,11 @@ async function pullImageBySkopeoRepo(
2222
): Promise<IPullableImage> {
2323
// Scan image by digest if exists, other way fallback tag
2424
const scanId = imageToPull.imageWithDigest ?? imageToPull.imageName;
25-
imageToPull.skopeoRepoType = SkopeoRepositoryType.DockerArchive;
26-
try {
27-
// copy docker archive image
28-
await skopeoCopy(
29-
scanId,
30-
imageToPull.fileSystemPath,
31-
imageToPull.skopeoRepoType,
32-
);
33-
} catch (dockerError) {
34-
imageToPull.skopeoRepoType = SkopeoRepositoryType.OciArchive;
35-
// copy oci archive image
36-
await skopeoCopy(
37-
scanId,
38-
imageToPull.fileSystemPath,
39-
imageToPull.skopeoRepoType,
40-
);
41-
}
25+
await skopeoCopy(
26+
scanId,
27+
imageToPull.fileSystemPath,
28+
imageToPull.skopeoRepoType,
29+
);
4230
return imageToPull;
4331
}
4432

@@ -120,22 +108,13 @@ export async function scanImages(
120108
): Promise<IScanResult[]> {
121109
const scannedImages: IScanResult[] = [];
122110

123-
for (const {
124-
imageName,
125-
fileSystemPath,
126-
imageWithDigest,
127-
skopeoRepoType,
128-
} of images) {
111+
for (const { imageName, fileSystemPath, imageWithDigest } of images) {
129112
try {
130113
const shouldIncludeAppVulns = true;
131-
const archiveType =
132-
skopeoRepoType == SkopeoRepositoryType.DockerArchive
133-
? 'docker-archive'
134-
: 'oci-archive';
135-
const dockerArchivePath = `${archiveType}:${fileSystemPath}`;
114+
const archivePath = `docker-archive:${fileSystemPath}`;
136115

137116
const pluginResponse = await scan({
138-
path: dockerArchivePath,
117+
path: archivePath,
139118
imageNameAndTag: imageName,
140119
'app-vulns': shouldIncludeAppVulns,
141120
});

src/scanner/images/skopeo.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ function prefixRespository(target: string, type: SkopeoRepositoryType): string {
2626
case SkopeoRepositoryType.ImageRegistry:
2727
return `${type}://${target}`;
2828
case SkopeoRepositoryType.DockerArchive:
29-
case SkopeoRepositoryType.OciArchive:
3029
return `${type}:${target}`;
3130
default:
3231
throw new Error(`Unhandled Skopeo repository type ${type}`);

src/scanner/images/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,5 @@ export interface IPullableImage {
1616
*/
1717
export enum SkopeoRepositoryType {
1818
DockerArchive = 'docker-archive',
19-
OciArchive = 'oci',
2019
ImageRegistry = 'docker',
21-
Directory = 'dir', // Note, skopeo marks this as a non-standard format
2220
}

src/scanner/index.ts

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import {
1717
ILocalWorkloadLocator,
1818
Telemetry,
1919
} from '../transmitter/types';
20-
import { IPullableImage, IScanImage } from './images/types';
20+
import {
21+
IPullableImage,
22+
IScanImage,
23+
SkopeoRepositoryType,
24+
} from './images/types';
2125
import {
2226
getWorkloadAlreadyScanned,
2327
getWorkloadImageAlreadyScanned,
@@ -29,7 +33,7 @@ export async function processWorkload(
2933
): Promise<void> {
3034
// every workload metadata references the same workload name, grab it from the first one
3135
const workloadName = workloadMetadata[0].name;
32-
const uniqueImages: IScanImage[] = getUniqueImages(workloadMetadata);
36+
const uniqueImages = getUniqueImages(workloadMetadata);
3337

3438
logger.info(
3539
{ workloadName, imageCount: uniqueImages.length },
@@ -74,42 +78,37 @@ export async function sendDeleteWorkloadRequest(
7478
}
7579

7680
export function getUniqueImages(workloadMetadata: IWorkload[]): IScanImage[] {
77-
const uniqueImages: { [key: string]: IScanImage } = workloadMetadata.reduce(
78-
(accum, meta) => {
79-
logger.info(
80-
{
81-
workloadName: workloadMetadata[0].name,
82-
name: meta.imageName,
83-
id: meta.imageId,
84-
},
85-
'image metadata',
86-
);
87-
// example: For DCR "redis:latest"
88-
// example: For GCR "gcr.io/test-dummy/redis:latest"
89-
// example: For ECR "291964488713.dkr.ecr.us-east-2.amazonaws.com/snyk/redis:latest"
90-
// meta.imageName can be different depends on CR
91-
const { imageName } = getImageParts(meta.imageName);
92-
// meta.imageId can be different depends on CR
93-
// example: For DCR "docker.io/library/redis@sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6"
94-
// example: For GCR "sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6"
95-
// example: For ECR "sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6"
96-
let digest: string | undefined = undefined;
97-
if (
98-
meta.imageId.lastIndexOf('@') > -1 ||
99-
meta.imageId.startsWith('sha')
100-
) {
101-
digest = meta.imageId.substring(meta.imageId.lastIndexOf('@') + 1);
102-
}
103-
104-
accum[meta.imageName] = {
105-
imageWithDigest: digest && `${imageName}@${digest}`,
106-
imageName: meta.imageName, // Image name with tag
107-
};
108-
109-
return accum;
110-
},
111-
{},
112-
);
81+
const uniqueImages = workloadMetadata.reduce((accum, meta) => {
82+
logger.info(
83+
{
84+
workloadName: workloadMetadata[0].name,
85+
name: meta.imageName,
86+
id: meta.imageId,
87+
},
88+
'image metadata',
89+
);
90+
// example: For DCR "redis:latest"
91+
// example: For GCR "gcr.io/test-dummy/redis:latest"
92+
// example: For ECR "291964488713.dkr.ecr.us-east-2.amazonaws.com/snyk/redis:latest"
93+
// meta.imageName can be different depends on CR
94+
const { imageName } = getImageParts(meta.imageName);
95+
// meta.imageId can be different depends on CR
96+
// example: For DCR "docker.io/library/redis@sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6"
97+
// example: For GCR "sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6"
98+
// example: For ECR "sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6"
99+
let digest: string | undefined = undefined;
100+
if (meta.imageId.lastIndexOf('@') > -1 || meta.imageId.startsWith('sha')) {
101+
digest = meta.imageId.substring(meta.imageId.lastIndexOf('@') + 1);
102+
}
103+
104+
accum[meta.imageName] = {
105+
imageWithDigest: digest && `${imageName}@${digest}`,
106+
imageName: meta.imageName, // Image name with tag
107+
skopeoRepoType: SkopeoRepositoryType.DockerArchive,
108+
};
109+
110+
return accum;
111+
}, {} as Record<string, IScanImage>);
113112

114113
return Object.values(uniqueImages);
115114
}

test/system/kind.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,10 @@ test('Kubernetes-Monitor with KinD', async (jestDoneCallback) => {
270270
{ type: 'imageOsReleasePrettyName', data: expect.any(String) },
271271
]),
272272
target: { image: 'docker-image|docker.io/library/java' },
273-
identity: { type: 'deb', args: { platform: 'linux/amd64' } },
273+
identity: {
274+
type: 'deb',
275+
args: { platform: 'linux/amd64' },
276+
},
274277
},
275278
{
276279
facts: [

0 commit comments

Comments
 (0)