Skip to content

Commit

Permalink
feat(versions): record own build info/version as properties, validate…
Browse files Browse the repository at this point in the history
… server version (#508)
  • Loading branch information
andrewazores authored Oct 15, 2024
1 parent 09a9afb commit 948ed98
Show file tree
Hide file tree
Showing 12 changed files with 575 additions and 7 deletions.
27 changes: 27 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,12 @@
<maven-source-plugin.version>3.3.1</maven-source-plugin.version>
<maven-javadoc-plugin.version>3.10.1</maven-javadoc-plugin.version>
<jreleaser-maven-plugin.version>1.14.0</jreleaser-maven-plugin.version>
<org.codehaus.mojo.exec.plugin.version>3.4.1</org.codehaus.mojo.exec.plugin.version>

<shade.prefix>io.cryostat.agent.shaded</shade.prefix>

<cryostat.server.version.min>4.0.0</cryostat.server.version.min>
<cryostat.server.version.max>5.0.0</cryostat.server.version.max>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -299,6 +303,29 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${org.codehaus.mojo.exec.plugin.version}</version>
<executions>
<execution>
<id>generate-git-version</id>
<phase>generate-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>git</executable>
<arguments>
<argument>rev-parse</argument>
<argument>--verify</argument>
<argument>HEAD</argument>
</arguments>
<outputFile>${project.build.directory}/classes/META-INF/gitinfo</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down
33 changes: 26 additions & 7 deletions src/main/java/io/cryostat/agent/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import javax.inject.Singleton;

import io.cryostat.agent.ConfigModule.URIRange;
import io.cryostat.agent.VersionInfo.Semver;
import io.cryostat.agent.harvest.Harvester;
import io.cryostat.agent.insights.InsightsAgentHelper;
import io.cryostat.agent.model.PluginInfo;
Expand All @@ -49,6 +50,7 @@
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import dagger.Component;
import org.apache.commons.lang3.tuple.Pair;
import org.eclipse.microprofile.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -155,7 +157,6 @@ public static void agentmain(String args, Instrumentation instrumentation) {
Thread t =
new Thread(
() -> {
log.info("Cryostat Agent starting...");
agent.accept(aa);
});
t.setDaemon(true);
Expand Down Expand Up @@ -200,12 +201,30 @@ static URI selfJarLocation() throws URISyntaxException {

@Override
public void accept(AgentArgs args) {
args.getProperties()
.forEach(
(k, v) -> {
log.trace("Set system property {} = {}", k, v);
System.setProperty(k, v);
});
Map<String, String> properties = new HashMap<>();
properties.putAll(args.getProperties());
properties.put("build.git.commit-hash", new BuildInfo().getGitInfo().getHash());
Semver agentVersion = Semver.UNKNOWN;
Pair<Semver, Semver> serverVersionRange = Pair.of(Semver.UNKNOWN, Semver.UNKNOWN);
try {
VersionInfo versionInfo = VersionInfo.load();
serverVersionRange = Pair.of(versionInfo.getServerMin(), versionInfo.getServerMax());
agentVersion = versionInfo.getAgentVersion();
properties.putAll(versionInfo.asMap());
} catch (IOException ioe) {
log.warn("Unable to read versions.properties file", ioe);
}
log.info(
"Cryostat Agent version {} (for Cryostat server version range [{}, {}) )"
+ " starting...",
agentVersion,
serverVersionRange.getLeft(),
serverVersionRange.getRight());
properties.forEach(
(k, v) -> {
log.trace("Set system property {} = {}", k, v);
System.setProperty(k, v);
});
AgentExitHandler agentExitHandler = null;
try {
final Client client = DaggerAgent_Client.builder().build();
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/io/cryostat/agent/BuildInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright The Cryostat Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.cryostat.agent;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

import io.cryostat.agent.util.ResourcesUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// FIXME this is adapted from Cryostat. Extract this to a reusable utility in libcryostat?
public class BuildInfo {

private static Logger log = LoggerFactory.getLogger(BuildInfo.class);
private static final String RESOURCE_LOCATION = "META-INF/gitinfo";

private final GitInfo gitinfo = new GitInfo();

public GitInfo getGitInfo() {
return gitinfo;
}

public static class GitInfo {
public String getHash() {
try (BufferedReader br =
new BufferedReader(
new InputStreamReader(
ResourcesUtil.getResourceAsStream(RESOURCE_LOCATION),
StandardCharsets.UTF_8))) {
return br.lines()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException(
String.format(
"Resource file %s is empty",
RESOURCE_LOCATION)))
.trim();
} catch (Exception e) {
log.warn("Version retrieval exception", e);
return "unknown";
}
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/io/cryostat/agent/CryostatClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import io.cryostat.agent.model.DiscoveryNode;
import io.cryostat.agent.model.PluginInfo;
import io.cryostat.agent.model.RegistrationInfo;
import io.cryostat.agent.model.ServerHealth;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
Expand Down Expand Up @@ -111,6 +112,22 @@ public class CryostatClient {
log.info("Using Cryostat baseuri {}", baseUri);
}

public CompletableFuture<ServerHealth> serverHealth() {
HttpGet req = new HttpGet(baseUri.resolve("/health"));
log.trace("{}", req);
return supply(req, res -> logResponse(req, res))
.thenApply(
res -> {
try (InputStream is = res.getEntity().getContent()) {
return mapper.readValue(is, ServerHealth.class);
} catch (IOException e) {
log.error("Unable to parse response as JSON", e);
throw new RegistrationException(e);
}
})
.whenComplete((v, t) -> req.reset());
}

public CompletableFuture<Boolean> checkRegistration(PluginInfo pluginInfo) {
if (!pluginInfo.isInitialized()) {
return CompletableFuture.completedFuture(false);
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/io/cryostat/agent/Registration.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.cryostat.agent;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
Expand All @@ -33,6 +34,7 @@
import java.util.function.Consumer;
import java.util.stream.Collectors;

import io.cryostat.agent.VersionInfo.Semver;
import io.cryostat.agent.model.DiscoveryNode;
import io.cryostat.agent.model.PluginInfo;
import io.cryostat.agent.util.StringUtils;
Expand Down Expand Up @@ -197,6 +199,29 @@ void tryRegister() {
return;
}
try {
cryostat.serverHealth()
.thenAccept(
health -> {
Semver cryostatSemver = health.cryostatSemver();
log.debug(
"Connected to Cryostat server: version {} , build {}",
cryostatSemver,
health.buildInfo().git().hash());
try {
VersionInfo version = VersionInfo.load();
if (!version.validateServerVersion(cryostatSemver)) {
log.warn(
"Cryostat server version {} is outside of expected"
+ " range [{}, {})",
cryostatSemver,
version.getServerMin(),
version.getServerMax());
}
} catch (IOException ioe) {
log.error("Unable to read versions.properties file", ioe);
}
})
.get();
URI credentialedCallback =
new URIBuilder(callback)
.setUserInfo("storedcredentials", String.valueOf(credentialId))
Expand Down
Loading

0 comments on commit 948ed98

Please sign in to comment.