127 lines
3.4 KiB
Dart
127 lines
3.4 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:podman/podman.dart';
|
|
|
|
Future<void> main(List<String> args) async {
|
|
if (args.isEmpty || args.contains('--help') || args.contains('-h')) {
|
|
_printUsage();
|
|
return;
|
|
}
|
|
|
|
final flags = args
|
|
.where((arg) => arg.startsWith('--'))
|
|
.toList(growable: false);
|
|
final positional = args
|
|
.where((arg) => !arg.startsWith('--'))
|
|
.toList(growable: false);
|
|
|
|
if (positional.length < 2) {
|
|
stderr.writeln('Provide a manifest name and at least one image reference.');
|
|
_printUsage();
|
|
exitCode = 64;
|
|
return;
|
|
}
|
|
|
|
final manifestName = positional.first;
|
|
final images = positional.sublist(1);
|
|
final pushDestination = _readOption(flags, 'push');
|
|
final cleanup = flags.contains('--cleanup');
|
|
final amend = flags.contains('--amend');
|
|
|
|
final annotations = _readKeyValueOptions(flags, 'annotation');
|
|
if (annotations.isEmpty) {
|
|
annotations['org.opencontainers.image.title'] = manifestName;
|
|
}
|
|
|
|
final client = PodmanClient();
|
|
try {
|
|
final created = await client.createManifest(
|
|
manifestName,
|
|
options: ManifestCreateOptions(
|
|
images: images,
|
|
all: true,
|
|
amend: amend,
|
|
annotations: annotations,
|
|
),
|
|
);
|
|
print('Created/updated manifest "$manifestName" (${created.id}).');
|
|
|
|
final exists = await client.manifestExists(manifestName);
|
|
print('Manifest exists: $exists');
|
|
|
|
final details = await client.inspectManifest(manifestName);
|
|
print('Schema version: ${details.schemaVersion}');
|
|
print('Media type: ${details.mediaType}');
|
|
print('Embedded manifests: ${details.manifests.length}');
|
|
|
|
if (pushDestination != null && pushDestination.isNotEmpty) {
|
|
final pushed = await client.pushManifest(manifestName, pushDestination);
|
|
print('Pushed to $pushDestination (${pushed.id}).');
|
|
}
|
|
|
|
if (cleanup) {
|
|
final result = await client.deleteManifest(
|
|
manifestName,
|
|
ignoreMissing: true,
|
|
);
|
|
print(
|
|
'Deleted entries: ${result.deleted.length}; untagged: ${result.untagged.length}',
|
|
);
|
|
}
|
|
} finally {
|
|
await client.close();
|
|
}
|
|
}
|
|
|
|
String? _readOption(List<String> args, String name) {
|
|
final prefix = '--$name=';
|
|
for (final arg in args) {
|
|
if (arg.startsWith(prefix)) {
|
|
return arg.substring(prefix.length);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Map<String, String> _readKeyValueOptions(List<String> args, String name) {
|
|
final prefix = '--$name=';
|
|
final output = <String, String>{};
|
|
|
|
for (final arg in args) {
|
|
if (!arg.startsWith(prefix)) {
|
|
continue;
|
|
}
|
|
|
|
final raw = arg.substring(prefix.length);
|
|
final index = raw.indexOf('=');
|
|
if (index <= 0 || index == raw.length - 1) {
|
|
continue;
|
|
}
|
|
|
|
final key = raw.substring(0, index);
|
|
final value = raw.substring(index + 1);
|
|
output[key] = value;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
void _printUsage() {
|
|
print('''
|
|
Manifest workflow example
|
|
|
|
Usage:
|
|
dart run example/manifest_workflow_example.dart <manifest-name> <image> [image ...] [options]
|
|
|
|
Examples:
|
|
dart run example/manifest_workflow_example.dart groupware-stack
|
|
quay.io/groupware/api:amd64 quay.io/groupware/api:arm64 --push=quay.io/groupware/api:latest
|
|
|
|
Options:
|
|
--annotation=<k=v> Add top-level annotation (repeatable)
|
|
--push=<destination> Push manifest to destination reference
|
|
--amend Amend if manifest already exists
|
|
--cleanup Delete manifest at end of run
|
|
--help, -h Show this help
|
|
''');
|
|
}
|