# getRootfs method

Future<bool> getRootfs(

1. String name,
2. String image,
3. {String? tag,
4. required TotalProgressCallback progress,
5. 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;
    }