Search in sources :

Example 1 with ArtifactDownloader

use of com.aws.greengrass.componentmanager.builtins.ArtifactDownloader in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManagerIntegTest method GIVEN_component_with_artifact_WHEN_prepareArtifacts_THEN_set_permissions_on_artifacts.

@Test
void GIVEN_component_with_artifact_WHEN_prepareArtifacts_THEN_set_permissions_on_artifacts() throws Exception {
    ComponentIdentifier ident = new ComponentIdentifier("aws.iot.gg.test.integ.perm", new Semver("1.0.0"));
    NucleusPaths nucleusPaths = kernel.getNucleusPaths();
    nucleusPaths.setComponentStorePath(tempRootDir);
    ComponentStore store = new ComponentStore(nucleusPaths, platformResolver, recipeLoader);
    kernel.getContext().put(ComponentStore.class, store);
    File scriptFile = store.resolveArtifactDirectoryPath(ident).resolve("script.sh").toFile();
    File emptyFile = store.resolveArtifactDirectoryPath(ident).resolve("empty.txt").toFile();
    ArtifactDownloader mockDownloader = mock(ArtifactDownloader.class);
    when(mockDownloader.downloadRequired()).thenReturn(true);
    when(mockDownloader.checkDownloadable()).thenReturn(Optional.empty());
    when(mockDownloader.getArtifactFile()).thenReturn(scriptFile).thenReturn(emptyFile);
    when(mockDownloader.canUnarchiveArtifact()).thenReturn(true);
    when(mockDownloader.canSetFilePermissions()).thenReturn(true);
    when(mockDownloader.checkComponentStoreSize()).thenReturn(true);
    when(mockDownloader.download()).thenAnswer(downloadToPath("script.sh", scriptFile)).thenAnswer(downloadToPath("empty.txt", emptyFile));
    ArtifactDownloaderFactory mockDownloaderFactory = mock(ArtifactDownloaderFactory.class);
    when(mockDownloaderFactory.getArtifactDownloader(any(), any(), any())).thenReturn(mockDownloader);
    kernel.getContext().put(ArtifactDownloaderFactory.class, mockDownloaderFactory);
    Files.copy(Paths.get(this.getClass().getResource("aws.iot.gg.test.integ.perm-1.0.0.yaml").toURI()), nucleusPaths.recipePath().resolve(PreloadComponentStoreHelper.getRecipeStorageFilenameFromTestSource("aws.iot.gg.test.integ.perm-1.0.0.yaml")));
    // THEN
    kernel.getContext().get(ComponentManager.class).preparePackages(Collections.singletonList(ident)).get(10, TimeUnit.SECONDS);
    assertThat(nucleusPaths.artifactPath(ident).resolve("script.sh"), hasPermission(FileSystemPermission.builder().ownerRead(true).groupRead(true).otherRead(true).ownerWrite(!PlatformResolver.isWindows && !SystemUtils.USER_NAME.equals(ROOT)).ownerExecute(true).groupExecute(true).build()));
    assertThat(nucleusPaths.artifactPath(ident).resolve("empty.txt"), hasPermission(FileSystemPermission.builder().ownerRead(true).groupRead(true).ownerWrite(!PlatformResolver.isWindows && !SystemUtils.USER_NAME.equals(ROOT)).build()));
}
Also used : ArtifactDownloaderFactory(com.aws.greengrass.componentmanager.builtins.ArtifactDownloaderFactory) NucleusPaths(com.aws.greengrass.util.NucleusPaths) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) Semver(com.vdurmont.semver4j.Semver) FileMatchers.anExistingFile(org.hamcrest.io.FileMatchers.anExistingFile) File(java.io.File) ArtifactDownloader(com.aws.greengrass.componentmanager.builtins.ArtifactDownloader) ComponentStore(com.aws.greengrass.componentmanager.ComponentStore) Test(org.junit.jupiter.api.Test)

Example 2 with ArtifactDownloader

use of com.aws.greengrass.componentmanager.builtins.ArtifactDownloader in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManagerIntegTest method GIVEN_component_with_archived_artifact_WHEN_prepareArtifacts_THEN_unarchives_artifacts.

@Test
void GIVEN_component_with_archived_artifact_WHEN_prepareArtifacts_THEN_unarchives_artifacts() throws Exception {
    // GIVEN
    ComponentIdentifier ident = new ComponentIdentifier("aws.iot.gg.test.integ.zip", new Semver("1.0.0"));
    NucleusPaths nucleusPaths = kernel.getNucleusPaths();
    nucleusPaths.setComponentStorePath(tempRootDir);
    ComponentStore store = new ComponentStore(nucleusPaths, platformResolver, recipeLoader);
    kernel.getContext().put(ComponentStore.class, store);
    ArtifactDownloader mockDownloader = mock(ArtifactDownloader.class);
    File artifactFile = store.resolveArtifactDirectoryPath(ident).resolve("zip.zip").toFile();
    when(mockDownloader.downloadRequired()).thenReturn(true);
    when(mockDownloader.checkDownloadable()).thenReturn(Optional.empty());
    when(mockDownloader.getArtifactFile()).thenReturn(artifactFile);
    when(mockDownloader.canUnarchiveArtifact()).thenReturn(true);
    when(mockDownloader.canSetFilePermissions()).thenReturn(true);
    when(mockDownloader.checkComponentStoreSize()).thenReturn(true);
    when(mockDownloader.download()).thenAnswer(downloadToPath("zip.zip", artifactFile));
    ArtifactDownloaderFactory mockDownloaderFactory = mock(ArtifactDownloaderFactory.class);
    when(mockDownloaderFactory.getArtifactDownloader(any(), any(), any())).thenReturn(mockDownloader);
    kernel.getContext().put(ArtifactDownloaderFactory.class, mockDownloaderFactory);
    Files.copy(Paths.get(this.getClass().getResource("aws.iot.gg.test.integ.zip-1.0.0.yaml").toURI()), nucleusPaths.recipePath().resolve(PreloadComponentStoreHelper.getRecipeStorageFilenameFromTestSource("aws.iot.gg.test.integ.zip-1.0.0.yaml")));
    // THEN
    kernel.getContext().get(ComponentManager.class).preparePackages(Collections.singletonList(ident)).get(10, TimeUnit.SECONDS);
    Path zipPath = nucleusPaths.unarchiveArtifactPath(ident, "zip");
    assertThat(zipPath.toFile(), anExistingDirectory());
    assertThat(zipPath.resolve("zip").toFile(), anExistingDirectory());
    assertThat(zipPath.resolve("zip").resolve("1").toFile(), anExistingFile());
    assertThat(zipPath.resolve("zip").resolve("2").toFile(), anExistingFile());
    // check everyone can enter dir
    assertThat(zipPath.resolve("zip"), hasPermission(FileSystemPermission.builder().ownerRead(true).ownerWrite(true).ownerExecute(true).groupRead(true).groupExecute(true).otherRead(true).otherExecute(true).build()));
    // check perms match what we gave
    FileSystemPermission allRead = FileSystemPermission.builder().ownerRead(true).groupRead(true).otherRead(true).ownerWrite(!PlatformResolver.isWindows && !SystemUtils.USER_NAME.equals(ROOT)).build();
    assertThat(zipPath.resolve("zip").resolve("1"), hasPermission(allRead));
    assertThat(zipPath.resolve("zip").resolve("2"), hasPermission(allRead));
}
Also used : Path(java.nio.file.Path) ArtifactDownloaderFactory(com.aws.greengrass.componentmanager.builtins.ArtifactDownloaderFactory) NucleusPaths(com.aws.greengrass.util.NucleusPaths) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) FileSystemPermission(com.aws.greengrass.util.FileSystemPermission) Semver(com.vdurmont.semver4j.Semver) ArtifactDownloader(com.aws.greengrass.componentmanager.builtins.ArtifactDownloader) FileMatchers.anExistingFile(org.hamcrest.io.FileMatchers.anExistingFile) File(java.io.File) ComponentStore(com.aws.greengrass.componentmanager.ComponentStore) Test(org.junit.jupiter.api.Test)

Example 3 with ArtifactDownloader

use of com.aws.greengrass.componentmanager.builtins.ArtifactDownloader in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManager method prepareArtifacts.

void prepareArtifacts(ComponentIdentifier componentIdentifier, List<ComponentArtifact> artifacts) throws PackageLoadingException, PackageDownloadException, InvalidArtifactUriException, InterruptedException {
    if (artifacts == null) {
        logger.atWarn().kv(PACKAGE_IDENTIFIER, componentIdentifier).log("Artifact list was null, expected non-null and non-empty");
        return;
    }
    Path packageArtifactDirectory = componentStore.resolveArtifactDirectoryPath(componentIdentifier);
    logger.atDebug().setEventType("downloading-package-artifacts").addKeyValue(PACKAGE_IDENTIFIER, componentIdentifier).log();
    for (ComponentArtifact artifact : artifacts) {
        ArtifactDownloader downloader = artifactDownloaderFactory.getArtifactDownloader(componentIdentifier, artifact, packageArtifactDirectory);
        if (downloader.downloadRequired()) {
            Optional<String> errorMsg = downloader.checkDownloadable();
            if (errorMsg.isPresent()) {
                throw new PackageDownloadException(String.format("Download required for artifact %s but device configs are invalid: %s", artifact.getArtifactUri(), errorMsg.get()));
            }
            // Check disk size limits before download
            // TODO: [P41215447]: Check artifact size for all artifacts to download early to fail early
            long usableSpaceBytes = componentStore.getUsableSpace();
            if (usableSpaceBytes < DEFAULT_MIN_DISK_AVAIL_BYTES) {
                throw new SizeLimitException(String.format("Disk space critical: %d bytes usable, %d bytes minimum allowed", usableSpaceBytes, DEFAULT_MIN_DISK_AVAIL_BYTES));
            }
            if (downloader.checkComponentStoreSize()) {
                long downloadSize = downloader.getDownloadSize();
                long storeContentSize = componentStore.getContentSize();
                if (storeContentSize + downloadSize > getConfiguredMaxSize()) {
                    throw new SizeLimitException(String.format("Component store size limit reached: %d bytes existing, %d bytes needed" + ", %d bytes maximum allowed total", storeContentSize, downloadSize, getConfiguredMaxSize()));
                }
            }
            try {
                downloader.download();
            } catch (IOException e) {
                throw new PackageDownloadException(String.format("Failed to download component %s artifact %s", componentIdentifier, artifact), e);
            }
        }
        if (downloader.canSetFilePermissions()) {
            File artifactFile = downloader.getArtifactFile();
            if (artifactFile != null) {
                try {
                    Permissions.setArtifactPermission(artifactFile.toPath(), artifact.getPermission().toFileSystemPermission());
                } catch (IOException e) {
                    throw new PackageDownloadException(String.format("Failed to change permissions of component %s artifact %s", componentIdentifier, artifact), e);
                }
            }
        }
        if (downloader.canUnarchiveArtifact()) {
            Unarchive unarchive = artifact.getUnarchive();
            if (unarchive == null) {
                unarchive = Unarchive.NONE;
            }
            File artifactFile = downloader.getArtifactFile();
            if (artifactFile != null && !unarchive.equals(Unarchive.NONE)) {
                try {
                    Path unarchivePath = nucleusPaths.unarchiveArtifactPath(componentIdentifier, getFileName(artifactFile));
                    unarchiver.unarchive(unarchive, artifactFile, unarchivePath);
                    if (downloader.canSetFilePermissions()) {
                        try {
                            Permissions.setArtifactPermission(unarchivePath, artifact.getPermission().toFileSystemPermission());
                        } catch (IOException e) {
                            throw new PackageDownloadException(String.format("Failed to change permissions of component %s artifact %s", componentIdentifier, artifact), e);
                        }
                    }
                } catch (IOException e) {
                    throw new PackageDownloadException(String.format("Failed to unarchive component %s artifact %s", componentIdentifier, artifact), e);
                }
            }
        }
    }
}
Also used : Path(java.nio.file.Path) SizeLimitException(com.aws.greengrass.componentmanager.exceptions.SizeLimitException) ComponentArtifact(com.aws.greengrass.componentmanager.models.ComponentArtifact) PackageDownloadException(com.aws.greengrass.componentmanager.exceptions.PackageDownloadException) Unarchive(com.amazon.aws.iot.greengrass.component.common.Unarchive) IOException(java.io.IOException) ArtifactDownloader(com.aws.greengrass.componentmanager.builtins.ArtifactDownloader) File(java.io.File)

Aggregations

ArtifactDownloader (com.aws.greengrass.componentmanager.builtins.ArtifactDownloader)3 File (java.io.File)3 ComponentStore (com.aws.greengrass.componentmanager.ComponentStore)2 ArtifactDownloaderFactory (com.aws.greengrass.componentmanager.builtins.ArtifactDownloaderFactory)2 ComponentIdentifier (com.aws.greengrass.componentmanager.models.ComponentIdentifier)2 NucleusPaths (com.aws.greengrass.util.NucleusPaths)2 Semver (com.vdurmont.semver4j.Semver)2 Path (java.nio.file.Path)2 FileMatchers.anExistingFile (org.hamcrest.io.FileMatchers.anExistingFile)2 Test (org.junit.jupiter.api.Test)2 Unarchive (com.amazon.aws.iot.greengrass.component.common.Unarchive)1 PackageDownloadException (com.aws.greengrass.componentmanager.exceptions.PackageDownloadException)1 SizeLimitException (com.aws.greengrass.componentmanager.exceptions.SizeLimitException)1 ComponentArtifact (com.aws.greengrass.componentmanager.models.ComponentArtifact)1 FileSystemPermission (com.aws.greengrass.util.FileSystemPermission)1 IOException (java.io.IOException)1