diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java index 96f19a6b87a8..a3db139b96ce 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java @@ -51,6 +51,8 @@ public class DatanodeDetails extends NodeImpl implements private String certSerialId; private String version; private long setupTime; + private String revision; + private String buildDate; /** * Constructs DatanodeDetails instance. DatanodeDetails.Builder is used @@ -63,11 +65,13 @@ public class DatanodeDetails extends NodeImpl implements * @param certSerialId serial id from SCM issued certificate. * @param version DataNode's version * @param setupTime the setup time of DataNode + * @param revision DataNodes's revision + * @param buildDate DataNodes's build timestamp */ @SuppressWarnings("parameternumber") private DatanodeDetails(UUID uuid, String ipAddress, String hostName, String networkLocation, List ports, String certSerialId, - String version, long setupTime) { + String version, long setupTime, String revision, String buildDate) { super(hostName, networkLocation, NetConstants.NODE_COST_DEFAULT); this.uuid = uuid; this.ipAddress = ipAddress; @@ -76,6 +80,8 @@ private DatanodeDetails(UUID uuid, String ipAddress, String hostName, this.certSerialId = certSerialId; this.version = version; this.setupTime = setupTime; + this.revision = revision; + this.buildDate = buildDate; } public DatanodeDetails(DatanodeDetails datanodeDetails) { @@ -89,6 +95,8 @@ public DatanodeDetails(DatanodeDetails datanodeDetails) { this.setParent(datanodeDetails.getParent()); this.version = datanodeDetails.version; this.setupTime = datanodeDetails.setupTime; + this.revision = datanodeDetails.revision; + this.buildDate = datanodeDetails.buildDate; } /** @@ -223,6 +231,12 @@ public static DatanodeDetails getFromProtoBuf( if (datanodeDetailsProto.hasSetupTime()) { builder.setSetupTime(datanodeDetailsProto.getSetupTime()); } + if (datanodeDetailsProto.hasRevision()) { + builder.setRevision(datanodeDetailsProto.getRevision()); + } + if (datanodeDetailsProto.hasBuildDate()) { + builder.setBuildDate(datanodeDetailsProto.getBuildDate()); + } return builder.build(); } @@ -271,6 +285,13 @@ public HddsProtos.DatanodeDetailsProto getProtoBufMessage() { builder.setSetupTime(getSetupTime()); + if (!Strings.isNullOrEmpty(getRevision())) { + builder.setRevision(getRevision()); + } + if (!Strings.isNullOrEmpty(getBuildDate())) { + builder.setBuildDate(getBuildDate()); + } + return builder.build(); } @@ -325,6 +346,8 @@ public static final class Builder { private String certSerialId; private String version; private long setupTime; + private String revision; + private String buildDate; /** * Default private constructor. To create Builder instance use @@ -425,6 +448,30 @@ public Builder setVersion(String ver) { return this; } + /** + * Sets the DataNode revision. + * + * @param rev the revision of DataNode. + * + * @return DatanodeDetails.Builder + */ + public Builder setRevision(String rev) { + this.revision = rev; + return this; + } + + /** + * Sets the DataNode build date. + * + * @param date the build date of DataNode. + * + * @return DatanodeDetails.Builder + */ + public Builder setBuildDate(String date) { + this.buildDate = date; + return this; + } + /** * Sets the DataNode setup time. * @@ -448,7 +495,8 @@ public DatanodeDetails build() { networkLocation = NetConstants.DEFAULT_RACK; } DatanodeDetails dn = new DatanodeDetails(id, ipAddress, hostName, - networkLocation, ports, certSerialId, version, setupTime); + networkLocation, ports, certSerialId, + version, setupTime, revision, buildDate); if (networkName != null) { dn.setNetworkName(networkName); } @@ -590,4 +638,40 @@ public long getSetupTime() { public void setSetupTime(long setupTime) { this.setupTime = setupTime; } + + /** + * Returns the DataNode revision. + * + * @return DataNode revision + */ + public String getRevision() { + return revision; + } + + /** + * Set DataNode revision. + * + * @param rev DataNode revision + */ + public void setRevision(String rev) { + this.revision = rev; + } + + /** + * Returns the DataNode build date. + * + * @return DataNode build date + */ + public String getBuildDate() { + return buildDate; + } + + /** + * Set DataNode build date. + * + * @param date DataNode build date + */ + public void setBuildDate(String date) { + this.buildDate = date; + } } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java index a4ff67ed86fc..ac6fba45066d 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java @@ -208,6 +208,9 @@ public void start() { datanodeDetails.setVersion( HddsVersionInfo.HDDS_VERSION_INFO.getVersion()); datanodeDetails.setSetupTime(Time.now()); + datanodeDetails.setRevision( + HddsVersionInfo.HDDS_VERSION_INFO.getRevision()); + datanodeDetails.setBuildDate(HddsVersionInfo.HDDS_VERSION_INFO.getDate()); TracingUtil.initTracing( "HddsDatanodeService." + datanodeDetails.getUuidString() .substring(0, 8), conf); diff --git a/hadoop-hdds/interface-client/src/main/proto/hdds.proto b/hadoop-hdds/interface-client/src/main/proto/hdds.proto index 243e8ecaced7..3eeb3a321927 100644 --- a/hadoop-hdds/interface-client/src/main/proto/hdds.proto +++ b/hadoop-hdds/interface-client/src/main/proto/hdds.proto @@ -45,6 +45,8 @@ message DatanodeDetailsProto { optional string networkLocation = 7; // Network topology location optional string version = 8; // Datanode version optional int64 setupTime = 9; + optional string revision = 10; + optional string buildDate = 11; // TODO(runzhiwang): when uuid is gone, specify 1 as the index of uuid128 and mark as required optional UUID uuid128 = 100; // UUID with 128 bits assigned to the Datanode. } diff --git a/hadoop-hdds/interface-client/src/main/proto/proto.lock b/hadoop-hdds/interface-client/src/main/proto/proto.lock index b27896c655e3..bc8828787d1c 100644 --- a/hadoop-hdds/interface-client/src/main/proto/proto.lock +++ b/hadoop-hdds/interface-client/src/main/proto/proto.lock @@ -1540,6 +1540,16 @@ "name": "setupTime", "type": "int64" }, + { + "id": 10, + "name": "revision", + "type": "string" + }, + { + "id": 11, + "name": "buildDate", + "type": "string" + }, { "id": 100, "name": "uuid128", @@ -1935,4 +1945,4 @@ } } ] -} +} \ No newline at end of file diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/NodeEndpoint.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/NodeEndpoint.java index 42832debfee1..bd022c4f1da2 100644 --- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/NodeEndpoint.java +++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/NodeEndpoint.java @@ -123,6 +123,8 @@ public Response getDatanodes() { .withUUid(datanode.getUuidString()) .withVersion(datanode.getVersion()) .withSetupTime(datanode.getSetupTime()) + .withRevision(datanode.getRevision()) + .withBuildDate(datanode.getBuildDate()) .build()); }); diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/DatanodeMetadata.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/DatanodeMetadata.java index 542654e96e2e..f75ea3233f37 100644 --- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/DatanodeMetadata.java +++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/DatanodeMetadata.java @@ -61,6 +61,12 @@ public final class DatanodeMetadata { @XmlElement(name = "setupTime") private long setupTime; + @XmlElement(name = "revision") + private String revision; + + @XmlElement(name = "buildDate") + private String buildDate; + private DatanodeMetadata(Builder builder) { this.hostname = builder.hostname; this.uuid = builder.uuid; @@ -72,6 +78,8 @@ private DatanodeMetadata(Builder builder) { this.leaderCount = builder.leaderCount; this.version = builder.version; this.setupTime = builder.setupTime; + this.revision = builder.revision; + this.buildDate = builder.buildDate; } public String getHostname() { @@ -114,6 +122,14 @@ public long getSetupTime() { return setupTime; } + public String getRevision() { + return revision; + } + + public String getBuildDate() { + return buildDate; + } + /** * Returns new builder class that builds a DatanodeMetadata. * @@ -138,6 +154,8 @@ public static final class Builder { private int leaderCount; private String version; private long setupTime; + private String revision; + private String buildDate; public Builder() { this.containers = 0; @@ -195,6 +213,16 @@ public Builder withSetupTime(long setupTime) { return this; } + public Builder withRevision(String revision) { + this.revision = revision; + return this; + } + + public Builder withBuildDate(String buildDate) { + this.buildDate = buildDate; + return this; + } + /** * Constructs DatanodeMetadata. * diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json index d8d6eac55a9f..8d61333b087b 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json @@ -43,7 +43,9 @@ "containers": 80, "leaderCount": 2, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574728775759 + "setupTime": 1574728775759, + "revision": "caf471111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T15:45Z" }, { "hostname": "localhost2.storage.enterprise.com", @@ -72,7 +74,9 @@ "containers": 8192, "leaderCount": 1, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724805059 + "setupTime": 1574724805059, + "revision": "caf471111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T15:45Z" }, { "hostname": "localhost3.storage.enterprise.com", @@ -107,7 +111,9 @@ "containers": 43, "leaderCount": 2, "version": "0.6.0-SNAPSHOT", - "setupTime": 1343544679543 + "setupTime": 1343544679543, + "revision": "aaf470000cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-19T13:45Z" }, { "hostname": "localhost4.storage.enterprise.com", @@ -123,7 +129,9 @@ "containers": 0, "leaderCount": 0, "version": "0.6.0-SNAPSHOT", - "setupTime": 1074724802059 + "setupTime": 1074724802059, + "revision": "aaf470000cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-19T13:45Z" }, { "hostname": "localhost5.storage.enterprise.com", @@ -152,7 +160,9 @@ "containers": 643, "leaderCount": 2, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724816029 + "setupTime": 1574724816029, + "revision": "aaf470000cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-19T13:45Z" }, { "hostname": "localhost6.storage.enterprise.com", @@ -181,7 +191,9 @@ "containers": 5, "leaderCount": 1, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724802059 + "setupTime": 1574724802059, + "revision": "aaf470000cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-19T13:45Z" }, { "hostname": "localhost7.storage.enterprise.com", @@ -216,7 +228,9 @@ "containers": 64, "leaderCount": 2, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724676009 + "setupTime": 1574724676009, + "revision": "aaf470000cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-19T13:45Z" }, { "hostname": "localhost8.storage.enterprise.com", @@ -245,7 +259,9 @@ "containers": 21, "leaderCount": 1, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724276050 + "setupTime": 1574724276050, + "revision": "caf471111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T15:45Z" }, { "hostname": "localhost9.storage.enterprise.com", @@ -274,7 +290,9 @@ "containers": 897, "leaderCount": 1, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724573011 + "setupTime": 1574724573011, + "revision": "caf471111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T15:45Z" }, { "hostname": "localhost10.storage.enterprise.com", @@ -309,7 +327,9 @@ "containers": 6754, "leaderCount": 2, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574723756059 + "setupTime": 1574723756059, + "revision": "caf471111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T15:45Z" }, { "hostname": "localhost11.storage.enterprise.com", @@ -338,7 +358,9 @@ "containers": 78, "leaderCount": 2, "version": "0.6.0-SNAPSHOT", - "setupTime": 1474724705783 + "setupTime": 1474724705783, + "revision": "ace991111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T10:45Z" }, { "hostname": "localhost12.storage.enterprise.com", @@ -367,7 +389,9 @@ "containers": 543, "leaderCount": 1, "version": "0.6.0-SNAPSHOT", - "setupTime": 1574724706232 + "setupTime": 1574724706232, + "revision": "ace991111cdb9168ec013f4526bb997aa513e079", + "buildDate": "2020-07-20T10:45Z" } ] }, diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index ceb7b51ac05c..856ab65ecabd 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -43,6 +43,8 @@ interface IDatanodeResponse { uuid: string; version: string; setupTime: number; + revision: string; + buildDate: string; } interface IDatanodesResponse { @@ -63,6 +65,8 @@ interface IDatanode { uuid: string; version: string; setupTime: number; + revision: string; + buildDate: string; } interface IPipeline { @@ -208,6 +212,24 @@ const COLUMNS = [ render: (uptime: number) => { return uptime > 0 ? moment(uptime).format('ll LTS') : 'NA'; } + }, + { + title: 'Revision', + dataIndex: 'revision', + key: 'revision', + isVisible: false, + isSearchable: true, + sorter: (a: IDatanode, b: IDatanode) => a.revision.localeCompare(b.revision), + defaultSortOrder: 'ascend' as const + }, + { + title: 'BuildDate', + dataIndex: 'buildDate', + key: 'buildDate', + isVisible: false, + isSearchable: true, + sorter: (a: IDatanode, b: IDatanode) => a.buildDate.localeCompare(b.buildDate), + defaultSortOrder: 'ascend' as const } ]; @@ -265,7 +287,9 @@ export class Datanodes extends React.Component, IDatanode containers: datanode.containers, leaderCount: datanode.leaderCount, version: datanode.version, - setupTime: datanode.setupTime + setupTime: datanode.setupTime, + revision: datanode.revision, + buildDate: datanode.buildDate }; }); const selectedColumns: IOption[] = COLUMNS.filter(column => column.isVisible).map(column => ({