Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix chown on copy issue #1448

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Deploy/stacks/dynamic/stack-clients/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stack-client:
image: ghcr.io/cambridge-cares/stack-client${IMAGE_SUFFIX}:1.40.0
image: ghcr.io/cambridge-cares/stack-client${IMAGE_SUFFIX}:1.40.1-fix-chown-on-copy-issue-SNAPSHOT
secrets:
- blazegraph_password
- postgis_password
Expand Down
2 changes: 1 addition & 1 deletion Deploy/stacks/dynamic/stack-clients/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.cmclinnovations</groupId>
<artifactId>stack-clients</artifactId>
<version>1.40.0</version>
<version>1.40.1-fix-chown-on-copy-issue-SNAPSHOT</version>

<name>Stack Clients</name>
<url>https://theworldavatar.io</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,15 @@ public void generateTiles(String database, String schema, CityTilerOptions optio
executeSimpleCommand(containerId, "cp",
CityTilerClient.DEFAULT_COLOUR_CONFIG_FILE, CityTilerClient.COLOUR_CONFIG_FILE);
} else {
sendFilesContent(containerId,
Map.of(COLOUR_CONFIG_FILE, colours.toString().getBytes()),
"/");
sendFileContent(containerId, Path.of(COLOUR_CONFIG_FILE), colours.toString().getBytes());
}

try (TempDir configDir = makeRemoteTempDir(containerId)) {

String configFilename = database + "-" + schema + ".yml";

sendFilesContent(containerId,
Map.of(configFilename, generateConfigFileContent(database, schema).getBytes()),
configDir.toString());
sendFileContent(containerId, configDir.getPath().resolve(configFilename),
generateConfigFileContent(database, schema).getBytes());

String crsIn = getCRSFromDatabase(database, schema);

Expand All @@ -87,7 +84,7 @@ public void generateTiles(String database, String schema, CityTilerOptions optio
stream.parallel();
}
stream.forEach(entry -> generateTileSet(options, containerId, crsIn, configFilePath,
outputDir, entry.getKey(), entry.getValue()));
outputDir, entry.getKey(), entry.getValue()));
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -67,6 +68,10 @@ protected final void sendFilesContent(String containerId, Map<String, byte[]> fi
DockerClient.getInstance().sendFilesContent(containerId, files, remoteDirPath);
}

protected final void sendFileContent(String containerId, Path filePath, byte[] content) {
DockerClient.getInstance().sendFileContent(containerId, filePath, content);
}

protected final void sendFiles(String containerId, String localDirPath, List<String> filePaths,
String remoteDirPath) {
DockerClient.getInstance().sendFiles(containerId, localDirPath, filePaths, remoteDirPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,7 @@ private void addFileContentToTar(TarArchiveOutputStream tar, String filePath, by
filePath = filePath.replace('\\', '/');
TarArchiveEntry entry = new TarArchiveEntry(filePath);
entry.setSize(fileContent.length);
entry.setMode(0755);
// Set the files' user and group to the default ones in that container
entry.setIds(1000, 1000);
entry.setMode(0600);
tar.putArchiveEntry(entry);
tar.write(fileContent);
tar.closeArchiveEntry();
Expand All @@ -412,21 +410,22 @@ private void sendTarFileContent(String containerId, String remoteDirPath, byte[]
CopyArchiveToContainerCmd copyArchiveToContainerCmd = internalClient
.copyArchiveToContainerCmd(containerId)) {
copyArchiveToContainerCmd.withTarInputStream(is)
.withCopyUIDGID(true)
.withRemotePath(remoteDirPath).exec();

}
}

private final class FileIterater implements Iterable<Entry<String, byte[]>>, AutoCloseable {
private final class FileIterator implements Iterable<Entry<String, byte[]>>, AutoCloseable {
Path dirPath;
private final Stream<Path> stream;

public FileIterater(String baseDir) throws IOException {
public FileIterator(String baseDir) throws IOException {
dirPath = Path.of(baseDir);
stream = Files.walk(Path.of(baseDir));
}

public FileIterater(String baseDir, Collection<String> relativeFilePaths) {
public FileIterator(String baseDir, Collection<String> relativeFilePaths) {
dirPath = Path.of(baseDir);
stream = relativeFilePaths.stream().map(dirPath::resolve);
}
Expand Down Expand Up @@ -459,8 +458,13 @@ public void sendFilesContent(String containerId, Map<String, byte[]> files, Stri
}
}

public void sendFileContent(String containerId, Path filePath, byte[] content) {
sendFilesContent(containerId, Map.of(filePath.getFileName().toString(), content),
filePath.getParent().toString());
}

public void sendFiles(String containerId, String localDirPath, List<String> filePaths, String remoteDirPath) {
try (FileIterater fileIterator = new FileIterater(localDirPath, filePaths)) {
try (FileIterator fileIterator = new FileIterator(localDirPath, filePaths)) {
sendFileEntries(containerId, remoteDirPath, fileIterator);
} catch (Exception ex) {
throw new RuntimeException("Failed to send the following files to '" + remoteDirPath + "':\n"
Expand All @@ -469,7 +473,7 @@ public void sendFiles(String containerId, String localDirPath, List<String> file
}

public void sendFolder(String containerId, String localDirPath, String remoteDirPath) {
try (FileIterater fileIterator = new FileIterater(localDirPath)) {
try (FileIterator fileIterator = new FileIterator(localDirPath)) {
sendFileEntries(containerId, remoteDirPath, fileIterator);
} catch (Exception ex) {
throw new RuntimeException("Failed to send files from folder '" + localDirPath
Expand Down Expand Up @@ -670,7 +674,7 @@ public void removeSecret(Secret secret) {
}

public String getDNSIPAddress() {
return "127.0.0.11";
return "127.0.0.11";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class GeoServerClient extends ClientWithEndpoint<RESTEndpointConfig> {
public static final Path SERVING_DIRECTORY = Path.of("/opt/geoserver_data/www");
private static final Path STATIC_DATA_DIRECTORY = SERVING_DIRECTORY.resolve("static_data");
private static final Path ICONS_DIRECTORY = SERVING_DIRECTORY.resolve("icons");
private static final String USER_PROJECTIONS_DIR = "/opt/geoserver_data/user_projections";
private static final String GEOSERVER_RASTER_INDEX_DATABASE_SUFFIX = "_geoserver_indices";
private static final String DIM_PREFIX = "dim_";

Expand Down Expand Up @@ -143,10 +144,8 @@ private void loadStaticFile(Path baseDirectory, GeoserverOtherStaticFile file) {
sendFolder(containerId, absSourcePath.toString(), absTargetPath.toString());
} else {
try {
sendFilesContent(containerId,
Map.of(file.getTarget(),
Files.readAllBytes(baseDirectory.resolve(file.getSource()))),
STATIC_DATA_DIRECTORY.toString());
sendFileContent(containerId, STATIC_DATA_DIRECTORY.resolve(file.getTarget()),
Files.readAllBytes(baseDirectory.resolve(file.getSource())));
} catch (IOException ex) {
throw new RuntimeException(
"Failed to serialise file '" + absSourcePath.toString() + "'.");
Expand Down Expand Up @@ -352,12 +351,11 @@ public void addProjectionsToGeoserver(String wktString, String srid) {
String geoserverContainerId = getContainerId("geoserver");
DockerClient dockerClient = DockerClient.getInstance();

dockerClient.makeDir(geoserverContainerId, "/opt/geoserver_data/user_projections");
dockerClient.makeDir(geoserverContainerId, USER_PROJECTIONS_DIR);

dockerClient.sendFilesContent(geoserverContainerId,
Map.of("epsg.properties",
(srid + "=" + wktString + "\n").getBytes()),
"/opt/geoserver_data/user_projections/");
sendFileContent(geoserverContainerId,
Path.of(USER_PROJECTIONS_DIR, "epsg.properties"),
(srid + "=" + wktString + "\n").getBytes());

GeoServerClient.getInstance().reload();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void updateOBDA(Path newMappingFilePath) {
.createTempOBDAFile(ontopMappingFilePath)) {
mapping.serialize(localTempOntopMappingFilePath.getPath());

sendFile(containerId, ontopMappingFilePath,
sendFileContent(containerId, ontopMappingFilePath,
Files.readAllBytes(localTempOntopMappingFilePath.getPath()));
}
} catch (IOException ex) {
Expand All @@ -96,7 +96,7 @@ public void uploadRules(List<Path> ruleFiles) {

try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
sparqlRules.write(outputStream);
sendFile(containerId, sparqlRulesFilePath, outputStream.toByteArray());
sendFileContent(containerId, sparqlRulesFilePath, outputStream.toByteArray());
} catch (IOException ex) {
throw new RuntimeException(
"Failed to write SPARQL Rules file.", ex);
Expand All @@ -109,7 +109,7 @@ private void writeTurtleToFile(Model model) {

try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
model.write(outputStream, "TURTLE");
sendFile(containerId, ontopOntologyFilePath, outputStream.toByteArray());
sendFileContent(containerId, ontopOntologyFilePath, outputStream.toByteArray());
} catch (IOException ex) {
throw new RuntimeException(ex);
}
Expand All @@ -123,8 +123,4 @@ private Path getFilePath(String containerId, String filenameKey) {
+ " not set through Docker for '" + getContainerName() + "' container."));
}

private void sendFile(String containerId, Path filePath, byte[] content) {
sendFilesContent(containerId, Map.of(filePath.getFileName().toString(), content),
filePath.getParent().toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -29,9 +28,7 @@ public void doPostStartUpConfiguration() {
try (InputStream is = CityTilerService.class
.getResourceAsStream("citytiler/citytiler_config_default.json")) {

dockerClient.sendFilesContent(dockerClient.getContainerId(TYPE),
Map.of(CityTilerClient.DEFAULT_COLOUR_CONFIG_FILE, is.readAllBytes()),
"/");
sendFileContent(CityTilerClient.DEFAULT_COLOUR_CONFIG_FILE, is.readAllBytes());

} catch (IOException ex) {
throw new RuntimeException("Failed to read in default citytiler colour config file.", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,14 @@ protected final void checkEnvironmentVariableNonNull(String key) {
+ "' to be specified in its config file.");
}

public final void sendFiles(Map<String, byte[]> files, String remoteDirPath) {
public final void sendFilesContent(Map<String, byte[]> files, String remoteDirPath) {
dockerClient.sendFilesContent(containerId, files, remoteDirPath);
}

public final void sendFileContent(String file, byte[] content) {
dockerClient.sendFileContent(containerId, Path.of(file), content);
}

public boolean fileExists(String filePath) {
return dockerClient.fileExists(containerId, filePath);
}
Expand All @@ -138,15 +142,13 @@ public final ComplexCommand createComplexCommand(String... cmd) {
return dockerClient.createComplexCommand(containerId, cmd);
}

protected final void downloadFileAndSendItToContainer(URL url, String folderPath,
String filename,
protected final void downloadFileAndSendItToContainer(URL url, String folderPath, String filename,
boolean overwrite) {
Path filePath = Path.of(folderPath, filename);
if (overwrite || !dockerClient.fileExists(containerId, filePath.toString())) {
if (overwrite || !fileExists(filePath.toString())) {
try (InputStream downloadStream = url.openStream()) {
byte[] bytes = downloadStream.readAllBytes();
Map<String, byte[]> files = Map.of(filename, bytes);
dockerClient.sendFilesContent(containerId, files, folderPath);
sendFileContent(filePath.toString(), bytes);
} catch (IOException ex) {
throw new RuntimeException("Failed to download file from '" + url + "' and send it to '"
+ folderPath + "' in the container '" + getName() + "'.", ex);
Expand Down Expand Up @@ -201,7 +203,7 @@ public void addServerSpecificNginxSettingsToLocationBlock(NgxBlock locationBlock
// configuration block
}

public String getDNSIPAddress(){
public String getDNSIPAddress() {
return dockerClient.getDNSIPAddress();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private void addConfig(NgxConfig config, String filepath) {
}

public void sendConfigs() {
sendFiles(files, NGINX_CONF_DIR);
sendFilesContent(files, NGINX_CONF_DIR);
executeCommand(CMD, "-s", "reload");
files.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void doPostStartUpConfiguration() {
DockerClient dockerClient = DockerClient.getInstance();
String containerId = dockerClient.getContainerId(containerName);
dockerClient.createComplexCommand(containerId, "chown", "ontop:ontop", String.join(" ", configDirs))
.withUser("root");
.withUser("root").exec();

OntopClient ontopClient = OntopClient.getInstance();
configFiles.forEach(f -> {
Expand All @@ -126,7 +126,7 @@ public void doPostStartUpConfiguration() {
ontopClient.uploadRules(List.of());
break;
default:
dockerClient.createComplexCommand(containerId, "touch", f).withUser("root").exec();
sendFileContent(f, "".getBytes());
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Stream;
Expand Down Expand Up @@ -53,17 +52,14 @@ public void doPostStartUpConfiguration() {
}

private void writePGPASSFile() {
sendFiles(Map.of(
PGPASS_FILE.getFileName().toString(),
sendFileContent(
PGPASS_FILE.toString(),
("localhost:"
+ endpointConfig.getPort() + ":"
+ "*:"
+ endpointConfig.getUsername() + ":"
+ endpointConfig.getPassword())
.getBytes()),
PGPASS_FILE.getParent().toString());

executeCommand("chmod", "0600", PGPASS_FILE.toString());
.getBytes());
}

private void copyJDBCDriverToVolume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ public void testSendFilesContent() {
Assert.assertFalse(dockerAPI.fileExists(containerId, filePath));
}

@Test
public void testSendFileContent() {
String remoteBaseDir = "/" + testName.getMethodName() + "/";
String filename = "file.txt";
String filePath = remoteBaseDir + filename;

Assert.assertFalse(dockerAPI.fileExists(containerId, filePath));
dockerAPI.sendFileContent(containerId, Path.of(filePath), TEST_MESSAGE.getBytes());
Assert.assertTrue(dockerAPI.fileExists(containerId, filePath));
dockerAPI.deleteFile(containerId, filePath);
Assert.assertFalse(dockerAPI.fileExists(containerId, filePath));
}

@Test
public void testSendFiles() throws IOException {
String remoteBaseDir = "/" + testName.getMethodName() + "/";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stack-data-uploader:
image: ghcr.io/cambridge-cares/stack-data-uploader${IMAGE_SUFFIX}:1.40.0
image: ghcr.io/cambridge-cares/stack-data-uploader${IMAGE_SUFFIX}:1.40.1-fix-chown-on-copy-issue-SNAPSHOT
secrets:
- blazegraph_password
- postgis_password
Expand Down
4 changes: 2 additions & 2 deletions Deploy/stacks/dynamic/stack-data-uploader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.cmclinnovations</groupId>
<artifactId>stack-data-uploader</artifactId>
<version>1.40.0</version>
<version>1.40.1-fix-chown-on-copy-issue-SNAPSHOT</version>

<name>Stack Data Uploader</name>
<url>https://theworldavatar.io</url>
Expand All @@ -29,7 +29,7 @@
<dependency>
<groupId>com.cmclinnovations</groupId>
<artifactId>stack-clients</artifactId>
<version>1.40.0</version>
<version>1.40.1-fix-chown-on-copy-issue-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
2 changes: 1 addition & 1 deletion Deploy/stacks/dynamic/stack-manager/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stack-manager:
image: ghcr.io/cambridge-cares/stack-manager${IMAGE_SUFFIX}:1.40.0
image: ghcr.io/cambridge-cares/stack-manager${IMAGE_SUFFIX}:1.40.1-fix-chown-on-copy-issue-SNAPSHOT
environment:
EXTERNAL_PORT: "${EXTERNAL_PORT-3838}"
STACK_BASE_DIR: "${STACK_BASE_DIR}"
Expand Down
Loading