private void buildOutputFiles()

in src/main/java/com/awslabs/aws/greengrass/provisioner/implementations/helpers/BasicDeploymentHelper.java [1612:1771]


    private void buildOutputFiles(DeploymentArguments deploymentArguments, GreengrassGroupName greengrassGroupName, Optional<CreateRoleAliasResponse> optionalCreateRoleAliasResponse, GreengrassGroupId greengrassGroupId, ThingName awsIotThingName, ThingArn awsIotThingArn, Optional<KeysAndCertificate> optionalCoreKeysAndCertificate, CertificateArn coreCertificateArn, boolean functionsRunningAsRoot) {
        if (deploymentArguments.scriptOutput) {
            installScriptVirtualTarEntries = Optional.of(new ArrayList<>());
        }

        if ((deploymentArguments.oemOutput) || (deploymentArguments.oemJsonOutput != null)) {
            oemVirtualTarEntries = Optional.of(new ArrayList<>());
        }

        if (!installScriptVirtualTarEntries.isPresent() &&
                !oemVirtualTarEntries.isPresent()) {
            log.warn("Not building any output files.  No output files specified (OEM or script)");
            return;
        }

        if (!optionalCoreKeysAndCertificate.isPresent() && (deploymentArguments.hsiParameters == null) && installScriptVirtualTarEntries.isPresent()) {
            // We don't have the keys, HSI parameters weren't set, and the user wants an installation script. This will not work.
            throw new RuntimeException(String.join("", "Could not find the core keys and certificate and no HSI options were set, cannot build a complete output file. Specify the [", DeploymentArguments.LONG_FORCE_CREATE_NEW_KEYS_OPTION, "] option if you need to regenerate the output files."));
        }

        log.info("Adding keys and certificate files to archive");

        String coreCertificatePath = String.join("/", ggConstants.getCertsDirectoryPrefix(), ggConstants.getCorePublicCertificateName());
        String coreCertificateArnPath = String.join(".", coreCertificatePath, "arn");

        if (optionalCoreKeysAndCertificate.isPresent()) {
            KeysAndCertificate coreKeysAndCertificate = optionalCoreKeysAndCertificate.get();

            String coreKeyPath = String.join("/", ggConstants.getCertsDirectoryPrefix(), ggConstants.getCorePrivateKeyName());

            addPrivateAndPublicKeyFiles(installScriptVirtualTarEntries, coreKeysAndCertificate, coreKeyPath, coreCertificatePath);
            addPrivateAndPublicKeyFiles(oemVirtualTarEntries, coreKeysAndCertificate, coreKeyPath, coreCertificatePath);
        } else {
            log.info("- Adding only client certificate to archive");

            CertificatePem coreCertificatePem = v2IotHelper.getCertificatePem(coreCertificateArn).get();
            byte[] pemBytes = coreCertificatePem.getPem().getBytes();

            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, coreCertificatePath, pemBytes, normalFilePermissions);
            archiveHelper.addVirtualTarEntry(oemVirtualTarEntries, coreCertificatePath, pemBytes, normalFilePermissions);
        }

        // Add a file for the certificate ARN so it is easier to find on the host or when using the Lambda version of GGP
        archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, coreCertificateArnPath, coreCertificateArn.getArn().getBytes(), normalFilePermissions);
        archiveHelper.addVirtualTarEntry(oemVirtualTarEntries, coreCertificateArnPath, coreCertificateArn.getArn().getBytes(), normalFilePermissions);

        ///////////////////////
        // Build config.json //
        ///////////////////////

        Region currentRegion = awsHelper.getCurrentRegion();

        log.info("Building config.json");
        String configJson = configFileHelper.generateConfigJson(ggConstants.getRootCaName(),
                ggConstants.getCorePublicCertificateName(),
                ggConstants.getCorePrivateKeyName(),
                awsIotThingArn,
                v2IotHelper.getEndpoint(V2IotEndpointType.DATA_ATS),
                currentRegion,
                deploymentArguments,
                functionsRunningAsRoot);

        log.info("Adding config.json to archive");
        String configJsonPath = String.join("/", ggConstants.getConfigDirectoryPrefix(), ggConstants.getConfigFileName());
        archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, configJsonPath, configJson.getBytes(), normalFilePermissions);
        archiveHelper.addVirtualTarEntry(oemVirtualTarEntries, configJsonPath, configJson.getBytes(), normalFilePermissions);

        /////////////////////////
        // Get the AWS root CA //
        /////////////////////////

        log.info("Getting root CA");
        String rootCaPath = String.join("/", ggConstants.getCertsDirectoryPrefix(), ggConstants.getRootCaName());

        // Use ifPresent here so we don't download the root CA if we don't need to add it to the archive
        installScriptVirtualTarEntries.ifPresent(archive -> archiveHelper.addVirtualTarEntry(archive, rootCaPath, ioHelper.download(ggConstants.getRootCaUrl()).getBytes(), normalFilePermissions));
        oemVirtualTarEntries.ifPresent(archive -> archiveHelper.addVirtualTarEntry(archive, rootCaPath, ioHelper.download(ggConstants.getRootCaUrl()).getBytes(), normalFilePermissions));

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Add some extra files to the OEM deployment so that Docker based deployments can do a redeployment on startup //
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        // Only create these files if we know the role alias
        if (optionalCreateRoleAliasResponse.isPresent()) {
            CreateRoleAliasResponse createRoleAliasResponse = optionalCreateRoleAliasResponse.get();

            addCredentialProviderFiles(oemVirtualTarEntries, greengrassGroupId, awsIotThingName, currentRegion, createRoleAliasResponse, deploymentArguments.hsiParameters);
            addCredentialProviderFiles(installScriptVirtualTarEntries, greengrassGroupId, awsIotThingName, currentRegion, createRoleAliasResponse, deploymentArguments.hsiParameters);
        }

        ///////////////////////
        // Build the scripts //
        ///////////////////////

        String baseGgShScriptName = ggVariables.getBaseGgScriptName(greengrassGroupName);
        String ggShScriptName = ggVariables.getGgShScriptName(greengrassGroupName);

        log.info("Adding scripts to archive");
        Optional<Architecture> optionalArchitecture = getArchitecture(deploymentArguments);

        // Skip this block if we're not generating the install script so we don't generate all of the other inner scripts
        if (installScriptVirtualTarEntries.isPresent()) {
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getStartScriptName(), scriptHelper.generateStartScript(optionalArchitecture.get()).getBytes(), scriptPermissions);
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getStopScriptName(), scriptHelper.generateStopScript(optionalArchitecture.get()).getBytes(), scriptPermissions);
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getCleanScriptName(), scriptHelper.generateCleanScript(optionalArchitecture.get(), baseGgShScriptName).getBytes(), scriptPermissions);
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getMonitorScriptName(), scriptHelper.generateMonitorScript(optionalArchitecture.get()).getBytes(), scriptPermissions);
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getSystemdScriptName(), scriptHelper.generateSystemdScript().getBytes(), scriptPermissions);
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getCredentialsScriptName(), scriptHelper.generateCredentialsScript().getBytes(), scriptPermissions);
            archiveHelper.addVirtualTarEntry(installScriptVirtualTarEntries, scriptHelper.getUpdateDependenciesScriptName(), scriptHelper.generateUpdateDependenciesScript().getBytes(), scriptPermissions);
        }

        ///////////////////////////
        // Package everything up //
        ///////////////////////////

        if (installScriptVirtualTarEntries.isPresent()) {
            log.info("Adding Greengrass binary to archive");
            Architecture architecture = optionalArchitecture.get();
            URL architectureUrl = getArchitectureUrl(deploymentArguments);

            // Use ifPresent here to avoid reading the file if it isn't necessary
            installScriptVirtualTarEntries.ifPresent(archive -> archiveHelper.addVirtualTarEntry(archive, architecture.getFilename(), ioHelper.readFile(architectureUrl), normalFilePermissions));

            log.info(String.join("", "Building script [", ggShScriptName, "]"));
            ByteArrayOutputStream ggScriptTemplate = new ByteArrayOutputStream();

            Try.run(() -> writePayload(architecture, ggScriptTemplate)).get();

            log.info(String.join("", "Writing script [", ggShScriptName, "]"));
            ioHelper.writeFile(ggShScriptName, ggScriptTemplate.toByteArray());
            ioHelper.makeExecutable(ggShScriptName);

            // Copy to S3 if necessary
            if (deploymentArguments.s3Bucket != null) {
                S3Bucket s3Bucket = ImmutableS3Bucket.builder().bucket(deploymentArguments.s3Bucket).build();
                S3Path s3Path = ImmutableS3Path.builder().path(deploymentArguments.s3Directory).build();
                File file = new File(ggShScriptName);
                v2S3Helper.copyToS3(s3Bucket, s3Path, file);
            }
        }

        if (oemVirtualTarEntries.isPresent()) {
            if (deploymentArguments.oemJsonOutput != null) {
                writeOemJsonOutput(oemVirtualTarEntries.get(), deploymentArguments.oemJsonOutput);
            } else {
                String oemArchiveName = ggVariables.getOemArchiveName(greengrassGroupName);
                log.info(String.join("", "Writing OEM file [", oemArchiveName, "]"));
                ioHelper.writeFile(oemArchiveName, getByteArrayOutputStream(oemVirtualTarEntries).get().toByteArray());
                ioHelper.makeExecutable(oemArchiveName);

                // Copy to S3 if necessary
                if (deploymentArguments.s3Bucket != null) {
                    S3Bucket s3Bucket = ImmutableS3Bucket.builder().bucket(deploymentArguments.s3Bucket).build();
                    S3Path s3Path = ImmutableS3Path.builder().path(deploymentArguments.s3Directory).build();
                    File file = new File(oemArchiveName);
                    v2S3Helper.copyToS3(s3Bucket, s3Path, file);
                }
            }
        }
    }