getRootfs method
- String name,
- String image,
- {String? tag,
- required TotalProgressCallback progress,
- bool skipDownload = false}
Putting layers into single tar file
Implementation
Future<bool> getRootfs(String name, String image,
{String? tag,
required TotalProgressCallback progress,
bool skipDownload = false}) async {
distroName = name;
var distroPath = getDistroPath().path;
// Add library to image name
if (image.split('/').length == 1) {
image = 'library/$image';
}
// Replace special chars
final imageName = filename(image, tag);
final tmpImagePath = (getTmpPath()..cd(imageName)).path;
// Create distro folder
var layers = 0;
bool done = false;
if (!skipDownload) {
await _download(image, tmpImagePath,
(current, total, currentStep, totalStep) {
layers = total;
if (kDebugMode) {
print('${current + 1}/$total');
}
progress(current, total, currentStep, totalStep);
if (current + 1 == total && currentStep == totalStep) {
done = true;
}
}, tag: tag);
}
// Wait for download to finish
while (!done && !skipDownload) {
await Future.delayed(const Duration(milliseconds: 500));
}
Notify.message('Extracting layers ...');
// Extract layers
// Write the compressed tar file to disk.
int retry = 0;
String outArchive = SafePath(distroPath).file('$imageName.tar.gz');
while (retry < 2) {
try {
Archive archive = Archive();
// More than one layer
if (layers != 1) {
for (var i = 0; i < layers; i++) {
// Read archives layers
if (kDebugMode) {
print('Extracting layer $i of $layers');
}
// progress(i, layers, -1, -1);
Notify.message('Extracting layer $i of $layers');
// In memory
final tarfile = GZipDecoder().decodeBytes(
File(SafePath(tmpImagePath).file('layer_$i.tar.gz'))
.readAsBytesSync());
final subArchive = TarDecoder().decodeBytes(tarfile);
// Add files to archive
for (final file in subArchive) {
archive.addFile(file);
if (kDebugMode && !file.name.contains('/')) {
if (kDebugMode) {
print('Adding root file ${file.name}');
}
}
}
}
// Archive as tar then gzip to disk
final tarfile = TarEncoder().encode(archive);
final gzData = GZipEncoder().encode(tarfile);
final fp = File(outArchive);
Notify.message('writingtodisk-text'.i18n());
fp.writeAsBytesSync(gzData!);
} else if (layers == 1) {
// Just copy the file
File(SafePath(tmpImagePath).file('layer_0.tar.gz'))
.copySync(outArchive);
}
retry = 2;
break;
} catch (e, stackTrace) {
retry++;
if (retry == 2) {
logDebug(e, stackTrace, null);
}
await Future.delayed(const Duration(seconds: 1));
if (kDebugMode) {
print('Retrying $retry');
}
}
}
Notify.message('creatinginstance-text'.i18n());
// Check if tar file is created
if (!File(outArchive).existsSync()) {
throw Exception('Tar file is not created');
}
// Wait for tar file to be created
await Future.delayed(const Duration(seconds: 1));
// Cleanup
await Directory(tmpImagePath).delete(recursive: true);
return true;
}