Example #1
0
  void createArchive(Path projectPath, Path output, Config overrideParams) throws IOException {
    out.println("Creating " + output + "...");

    ProjectArchive project =
        projectLoader.load(projectPath, WorkflowResourceMatcher.defaultMatcher(), overrideParams);
    ArchiveMetadata meta = project.getArchiveMetadata();

    try (TarArchiveOutputStream tar =
        new TarArchiveOutputStream(new GzipCompressorOutputStream(Files.newOutputStream(output)))) {
      // default mode for file names longer than 100 bytes is throwing an exception (LONGFILE_ERROR)
      tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);

      project.listFiles(
          (resourceName, absPath) -> {
            if (!Files.isDirectory(absPath)) {
              out.println("  Archiving " + resourceName);

              TarArchiveEntry e = buildTarArchiveEntry(project, absPath, resourceName);
              tar.putArchiveEntry(e);
              if (e.isSymbolicLink()) {
                out.println("    symlink -> " + e.getLinkName());
              } else {
                try (InputStream in = Files.newInputStream(absPath)) {
                  ByteStreams.copy(in, tar);
                }
                tar.closeArchiveEntry();
              }
            }
          });

      // create .digdag.dig
      // TODO set default time zone if not set?
      byte[] metaBody = yamlMapper.toYaml(meta).getBytes(StandardCharsets.UTF_8);
      TarArchiveEntry metaEntry = new TarArchiveEntry(ArchiveMetadata.FILE_NAME);
      metaEntry.setSize(metaBody.length);
      metaEntry.setModTime(new Date());
      tar.putArchiveEntry(metaEntry);
      tar.write(metaBody);
      tar.closeArchiveEntry();
    }

    out.println("Workflows:");
    for (WorkflowDefinition workflow : meta.getWorkflowList().get()) {
      out.println("  " + workflow.getName());
    }
    out.println("");
  }
Example #2
0
  private TarArchiveEntry buildTarArchiveEntry(ProjectArchive project, Path absPath, String name)
      throws IOException {
    TarArchiveEntry e;
    if (Files.isSymbolicLink(absPath)) {
      e = new TarArchiveEntry(name, TarConstants.LF_SYMLINK);
      Path rawDest = Files.readSymbolicLink(absPath);
      Path normalizedAbsDest = absPath.getParent().resolve(rawDest).normalize();
      try {
        project.pathToResourceName(normalizedAbsDest);
      } catch (IllegalArgumentException ex) {
        throw new IllegalArgumentException("Invalid symbolic link: " + ex.getMessage());
      }
      // absolute path will be invalid on a server. convert it to a relative path
      Path normalizedRelativeDest = absPath.getParent().relativize(normalizedAbsDest);

      String linkName = normalizedRelativeDest.toString();

      // TarArchiveEntry(File) does this normalization but setLinkName doesn't. So do it here:
      linkName = linkName.replace(File.separatorChar, '/');
      e.setLinkName(linkName);
    } else {
      e = new TarArchiveEntry(absPath.toFile(), name);
      try {
        int mode = 0;
        for (PosixFilePermission perm : Files.getPosixFilePermissions(absPath)) {
          switch (perm) {
            case OWNER_READ:
              mode |= 0400;
              break;
            case OWNER_WRITE:
              mode |= 0200;
              break;
            case OWNER_EXECUTE:
              mode |= 0100;
              break;
            case GROUP_READ:
              mode |= 0040;
              break;
            case GROUP_WRITE:
              mode |= 0020;
              break;
            case GROUP_EXECUTE:
              mode |= 0010;
              break;
            case OTHERS_READ:
              mode |= 0004;
              break;
            case OTHERS_WRITE:
              mode |= 0002;
              break;
            case OTHERS_EXECUTE:
              mode |= 0001;
              break;
            default:
              // ignore
          }
        }
        e.setMode(mode);
      } catch (UnsupportedOperationException ex) {
        // ignore custom mode
      }
    }
    return e;
  }