Introduce edge upgrade documentation

This commit is contained in:
Andrii Landiak 2023-11-21 16:51:27 +02:00
parent 3c90b9cf2f
commit deeb0208a9
23 changed files with 494 additions and 29 deletions

View File

@ -1,4 +1,4 @@
Here is the list of commands, that can be used to quickly install ThingsBoard Edge on RHEL/CentOS 7/8 and connect to the cloud. Here is the list of commands, that can be used to quickly install ThingsBoard Edge on RHEL/CentOS 7/8 and connect to the server.
#### Prerequisites #### Prerequisites
Before continue to installation execute the following commands in order to install necessary tools: Before continue to installation execute the following commands in order to install necessary tools:

View File

@ -1,4 +1,4 @@
Here is the list of commands, that can be used to quickly install ThingsBoard Edge using docker compose and connect to the cloud. Here is the list of commands, that can be used to quickly install ThingsBoard Edge using docker compose and connect to the server.
#### Prerequisites #### Prerequisites

View File

@ -1,4 +1,4 @@
Here is the list of commands, that can be used to quickly install ThingsBoard Edge on Ubuntu Server and connect to the cloud. Here is the list of commands, that can be used to quickly install ThingsBoard Edge on Ubuntu Server and connect to the server.
#### Install Java 11 (OpenJDK) #### Install Java 11 (OpenJDK)
ThingsBoard service is running on Java 11. Follow these instructions to install OpenJDK 11: ThingsBoard service is running on Java 11. Follow these instructions to install OpenJDK 11:

View File

@ -0,0 +1,30 @@
#### Upgrading to ${TB_EDGE_VERSION_TITLE}
**NOTE**:These steps are applicable for ThingsBoard Edge ${CURRENT_TB_EDGE_VERSION} version.
**ThingsBoard Edge package download**
```bash
wget https://github.com/thingsboard/thingsboard-edge/releases/download/v${TB_EDGE_TAG}/tb-edge-${TB_EDGE_TAG}.rpm
{:copy-code}
```
#### ThingsBoard Edge service upgrade
Stop ThingsBoard Edge service if it is running:
```bash
sudo service tb-edge stop
{:copy-code}
```
```bash
sudo rpm -Uvh tb-edge-${TB_EDGE_TAG}.rpm
{:copy-code}
```
${UPGRADE_DB}
Start the service
```bash
sudo service tb-edge start
{:copy-code}
```

View File

@ -0,0 +1,15 @@
#### Upgrading to ${TB_EDGE_VERSION}
**NOTE**:These steps are applicable for ThingsBoard Edge ${CURRENT_TB_EDGE_VERSION} version.
Execute the following command to pull **${TB_EDGE_VERSION}** image:
```bash
docker pull thingsboard/tb-edge:${TB_EDGE_VERSION}
{:copy-code}
```
${STOP_SERVICE}
${UPGRADE_DB}
Make sure your image is the set to tb-edge-${TB_EDGE_VERSION}.

View File

@ -0,0 +1,7 @@
Execute the following commands to up this docker compose directly:
```bash
docker compose up -d
docker compose logs -f mytbedge
{:copy-code}
```

View File

@ -0,0 +1,11 @@
Set the terminal in the directory which contains the `docker-compose.yml` file and execute the following command to stop
and remove currently running TB Edge container (if its still running):
```bash
make <span style="color:red;">docker-compose.yml</span>
```bash
docker compose stop
docker compose rm mytbedge
{:copy-code}
```

View File

@ -0,0 +1,53 @@
Create docker compose file for ThingsBoard Edge upgrade process:
```bash
nano docker-compose-upgrade.yml
{:copy-code}
```
Add the following lines to the yml file:
```bash
version: '3.0'
services:
mytbedge:
restart: on-failure
image: "thingsboard/tb-edge:${TB_EDGE_VERSION}"
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/tb-edge
volumes:
- ~/.mytb-edge-data:/data
- ~/.mytb-edge-logs:/var/log/tb-edge
entrypoint: upgrade-tb-edge.sh
postgres:
restart: always
image: "postgres:12"
ports:
- "5432"
environment:
POSTGRES_DB: tb-edge
POSTGRES_PASSWORD: postgres
volumes:
- ~/.mytb-edge-data/db:/var/lib/postgresql/data
{:copy-code}
```
Execute the following command to start upgrade process:
```bash
docker compose -f docker-compose-upgrade.yml up
{:copy-code}
```
Once upgrade process successfully completed, exit from the docker-compose shell by this combination:
```text
Ctrl + C
```
Execute the following command to stop TB Edge upgrade container:
```bash
docker compose -f docker-compose-upgrade.yml stop
{:copy-code}
```

View File

@ -0,0 +1,26 @@
Here is the list of commands, that can be used to quickly upgrade ThingsBoard Edge on Docker (Linux or MacOS).
#### Prepare for upgrading ThingsBoard Edge
Set the terminal in the directory which contains the `docker-compose.yml` file and execute the following command
to stop and remove currently running TB Edge container:
```bash
docker compose stop
docker compose rm mytbedge
{:copy-code}
```
If you still rely on Docker Compose as docker-compose (with a hyphen) here is the list of the above commands:
docker-compose stop
docker-compose rm mytbedge
#### Backup Database
Make a copy of the database folder before upgrading:
```bash
sudo cp -r ~/.mytb-edge-data/db ~/.mytb-edge-db-BACKUP
{:copy-code}
```
```bash
make <span style="color:red;">docker-compose.yml</span>

View File

@ -0,0 +1,6 @@
Start the service
```bash
sudo service tb-edge start
{:copy-code}
```

View File

@ -0,0 +1,6 @@
Stop ThingsBoard Edge service if it is running:
```bash
sudo service tb-edge stop
{:copy-code}
```

View File

@ -0,0 +1,19 @@
#### Upgrading to ${TB_EDGE_VERSION}
**NOTE**:These steps are applicable for ThingsBoard Edge ${CURRENT_TB_EDGE_VERSION} version.
**ThingsBoard Edge package download**
```bash
wget https://github.com/thingsboard/thingsboard-edge/releases/download/v${TB_EDGE_TAG}/tb-edge-${TB_EDGE_TAG}.deb
{:copy-code}
```
#### ThingsBoard Edge service upgrade
${STOP_SERVICE}
```bash
sudo dpkg -i tb-edge-${TB_EDGE_TAG}.deb
{:copy-code}
```
${UPGRADE_DB}

View File

@ -0,0 +1,8 @@
**NOTE**: Package installer may ask you to merge your tb-edge configuration. It is preferred to use **merge option** to make sure that all your previous parameters will not be overwritten.
Execute regular upgrade script:
```bash
sudo /usr/share/tb-edge/bin/install/upgrade.sh --fromVersion=${CURRENT_TB_EDGE_VERSION}
{:copy-code}
```

View File

@ -0,0 +1,37 @@
Here is the list of commands, that can be used to quickly upgrade ThingsBoard Edge on RHEL/CentOS 7/8.
#### Prepare for upgrading ThingsBoard Edge
Stop ThingsBoard Edge service:
```bash
sudo systemctl stop tb-edge
{:copy-code}
```
#### Backup Database
Make a backup of the database before upgrading.
**Make sure you have enough space to place a backup of the database.**
Check database size:
```bash
sudo -u postgres psql -c "SELECT pg_size_pretty( pg_database_size('tb_edge') );"
{:copy-code}
```
Check free space:
```bash
df -h /
{:copy-code}
```
If there is enough free space - make a backup:
```bash
sudo -Hiu postgres pg_dump tb_edge > tb_edge.sql.bak
{:copy-code}
```
Check backup file created successfully.

View File

@ -39,7 +39,7 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo; import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeInstallInstructions; import org.thingsboard.server.common.data.edge.EdgeInstructions;
import org.thingsboard.server.common.data.edge.EdgeSearchQuery; import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -60,6 +60,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.EdgeBulkImportService; import org.thingsboard.server.service.edge.EdgeBulkImportService;
import org.thingsboard.server.service.edge.instructions.EdgeInstallService; import org.thingsboard.server.service.edge.instructions.EdgeInstallService;
import org.thingsboard.server.service.edge.instructions.EdgeUpgradeService;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService; import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import org.thingsboard.server.service.entitiy.edge.TbEdgeService; import org.thingsboard.server.service.entitiy.edge.TbEdgeService;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
@ -102,6 +103,7 @@ public class EdgeController extends BaseController {
private final TbEdgeService tbEdgeService; private final TbEdgeService tbEdgeService;
private final Optional<EdgeRpcService> edgeRpcServiceOpt; private final Optional<EdgeRpcService> edgeRpcServiceOpt;
private final Optional<EdgeInstallService> edgeInstallServiceOpt; private final Optional<EdgeInstallService> edgeInstallServiceOpt;
private final Optional<EdgeUpgradeService> edgeUpgradeServiceOpt;
public static final String EDGE_ID = "edgeId"; public static final String EDGE_ID = "edgeId";
public static final String EDGE_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. " + public static final String EDGE_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. " +
@ -553,16 +555,16 @@ public class EdgeController extends BaseController {
return edgeBulkImportService.processBulkImport(request, user); return edgeBulkImportService.processBulkImport(request, user);
} }
@ApiOperation(value = "Get Edge Docker Install Instructions (getEdgeDockerInstallInstructions)", @ApiOperation(value = "Get Edge Install Instructions (getEdgeInstallInstructions)",
notes = "Get a docker install instructions for provided edge id." + TENANT_AUTHORITY_PARAGRAPH, notes = "Get a docker install instructions for provided edge id." + TENANT_AUTHORITY_PARAGRAPH,
produces = MediaType.APPLICATION_JSON_VALUE) produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/instructions/{edgeId}/{method}", method = RequestMethod.GET) @RequestMapping(value = "/edge/instructions/install/{edgeId}/{method}", method = RequestMethod.GET)
@ResponseBody @ResponseBody
public EdgeInstallInstructions getEdgeDockerInstallInstructions( public EdgeInstructions getEdgeInstallInstructions(
@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("edgeId") String strEdgeId, @PathVariable("edgeId") String strEdgeId,
@ApiParam(value = "Installation method ('docker', 'ubuntu' or 'centos')") @ApiParam(value = "Installation method ('docker', 'ubuntu' or 'centos')", allowableValues = "docker,ubuntu,centos")
@PathVariable("method") String installationMethod, @PathVariable("method") String installationMethod,
HttpServletRequest request) throws ThingsboardException { HttpServletRequest request) throws ThingsboardException {
if (isEdgesEnabled() && edgeInstallServiceOpt.isPresent()) { if (isEdgesEnabled() && edgeInstallServiceOpt.isPresent()) {
@ -574,4 +576,27 @@ public class EdgeController extends BaseController {
throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL); throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
} }
} }
@ApiOperation(value = "Get Edge Upgrade Instructions (getEdgeUpgradeInstructions)",
notes = "Get a docker install instructions for provided edge id." + TENANT_AUTHORITY_PARAGRAPH,
produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/instructions/upgrade/{edgeId}/{edgeVersion}/{method}", method = RequestMethod.GET)
@ResponseBody
public EdgeInstructions getEdgeUpgradeInstructions(
@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("edgeId") String strEdgeId,
@ApiParam(value = "Edge version", required = true)
@PathVariable("edgeVersion") String edgeVersion,
@ApiParam(value = "Installation method ('docker', 'ubuntu' or 'centos')", allowableValues = "docker,ubuntu,centos")
@PathVariable("method") String method) throws Exception {
if (isEdgesEnabled() && edgeUpgradeServiceOpt.isPresent()) {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
edgeId = checkNotNull(edgeId);
Edge edge = checkEdgeId(edgeId, Operation.READ);
return checkNotNull(edgeUpgradeServiceOpt.get().getUpgradeInstructions(getTenantId(), edge, edgeVersion, method));
} else {
throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
}
}
} }

View File

@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInstallInstructions; import org.thingsboard.server.common.data.edge.EdgeInstructions;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.InstallScripts;
@ -40,8 +40,8 @@ import java.nio.file.Paths;
public class DefaultEdgeInstallService implements EdgeInstallService { public class DefaultEdgeInstallService implements EdgeInstallService {
private static final String EDGE_DIR = "edge"; private static final String EDGE_DIR = "edge";
private static final String INSTRUCTIONS_DIR = "instructions";
private static final String EDGE_INSTALL_INSTRUCTIONS_DIR = "install_instructions"; private static final String INSTALL_DIR = "install";
private final InstallScripts installScripts; private final InstallScripts installScripts;
@ -55,7 +55,7 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
private String appVersion; private String appVersion;
@Override @Override
public EdgeInstallInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request) { public EdgeInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request) {
switch (installationMethod.toLowerCase()) { switch (installationMethod.toLowerCase()) {
case "docker": case "docker":
return getDockerInstallInstructions(edge, request); return getDockerInstallInstructions(edge, request);
@ -68,7 +68,7 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
} }
} }
private EdgeInstallInstructions getDockerInstallInstructions(Edge edge, HttpServletRequest request) { private EdgeInstructions getDockerInstallInstructions(Edge edge, HttpServletRequest request) {
String dockerInstallInstructions = readFile(resolveFile("docker", "instructions.md")); String dockerInstallInstructions = readFile(resolveFile("docker", "instructions.md"));
String baseUrl = request.getServerName(); String baseUrl = request.getServerName();
if (baseUrl.contains("localhost") || baseUrl.contains("127.0.0.1")) { if (baseUrl.contains("localhost") || baseUrl.contains("127.0.0.1")) {
@ -83,26 +83,26 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
edgeVersion = edgeVersion.replace("-SNAPSHOT", ""); edgeVersion = edgeVersion.replace("-SNAPSHOT", "");
dockerInstallInstructions = dockerInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion); dockerInstallInstructions = dockerInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
dockerInstallInstructions = replacePlaceholders(dockerInstallInstructions, edge); dockerInstallInstructions = replacePlaceholders(dockerInstallInstructions, edge);
return new EdgeInstallInstructions(dockerInstallInstructions); return new EdgeInstructions(dockerInstallInstructions);
} }
private EdgeInstallInstructions getUbuntuInstallInstructions(Edge edge, HttpServletRequest request) { private EdgeInstructions getUbuntuInstallInstructions(Edge edge, HttpServletRequest request) {
String ubuntuInstallInstructions = readFile(resolveFile("ubuntu", "instructions.md")); String ubuntuInstallInstructions = readFile(resolveFile("ubuntu", "instructions.md"));
ubuntuInstallInstructions = replacePlaceholders(ubuntuInstallInstructions, edge); ubuntuInstallInstructions = replacePlaceholders(ubuntuInstallInstructions, edge);
ubuntuInstallInstructions = ubuntuInstallInstructions.replace("${BASE_URL}", request.getServerName()); ubuntuInstallInstructions = ubuntuInstallInstructions.replace("${BASE_URL}", request.getServerName());
String edgeVersion = appVersion.replace("-SNAPSHOT", ""); String edgeVersion = appVersion.replace("-SNAPSHOT", "");
ubuntuInstallInstructions = ubuntuInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion); ubuntuInstallInstructions = ubuntuInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
return new EdgeInstallInstructions(ubuntuInstallInstructions); return new EdgeInstructions(ubuntuInstallInstructions);
} }
private EdgeInstallInstructions getCentosInstallInstructions(Edge edge, HttpServletRequest request) { private EdgeInstructions getCentosInstallInstructions(Edge edge, HttpServletRequest request) {
String centosInstallInstructions = readFile(resolveFile("centos", "instructions.md")); String centosInstallInstructions = readFile(resolveFile("centos", "instructions.md"));
centosInstallInstructions = replacePlaceholders(centosInstallInstructions, edge); centosInstallInstructions = replacePlaceholders(centosInstallInstructions, edge);
centosInstallInstructions = centosInstallInstructions.replace("${BASE_URL}", request.getServerName()); centosInstallInstructions = centosInstallInstructions.replace("${BASE_URL}", request.getServerName());
String edgeVersion = appVersion.replace("-SNAPSHOT", ""); String edgeVersion = appVersion.replace("-SNAPSHOT", "");
centosInstallInstructions = centosInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion); centosInstallInstructions = centosInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
return new EdgeInstallInstructions(centosInstallInstructions); return new EdgeInstructions(centosInstallInstructions);
} }
private String replacePlaceholders(String instructions, Edge edge) { private String replacePlaceholders(String instructions, Edge edge) {
@ -127,6 +127,6 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
} }
private Path getEdgeInstallInstructionsDir() { private Path getEdgeInstallInstructionsDir() {
return Paths.get(installScripts.getDataDir(), InstallScripts.JSON_DIR, EDGE_DIR, EDGE_INSTALL_INSTRUCTIONS_DIR); return Paths.get(installScripts.getDataDir(), InstallScripts.JSON_DIR, EDGE_DIR, INSTRUCTIONS_DIR, INSTALL_DIR);
} }
} }

View File

@ -0,0 +1,190 @@
/**
* Copyright © 2016-2023 The Thingsboard 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 org.thingsboard.server.service.edge.instructions;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInstructions;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.install.InstallScripts;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
@Service
@Slf4j
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true")
@TbCoreComponent
public class DefaultEdgeUpgradeService implements EdgeUpgradeService {
private static final HashMap<String, UpgradeInfo> upgradeVersionHashMap;
static {
upgradeVersionHashMap = new HashMap<>();
upgradeVersionHashMap.put("3.6.0", new UpgradeInfo(true, "3.6.1"));
upgradeVersionHashMap.put("3.6.1", new UpgradeInfo(true, "3.6.2"));
upgradeVersionHashMap.put("3.6.2", new UpgradeInfo(true, null));
}
private static final String EDGE_DIR = "edge";
private static final String INSTRUCTIONS_DIR = "instructions";
private static final String UPGRADE_DIR = "upgrade";
private final InstallScripts installScripts;
private final AttributesService attributesService;
@Value("${app.version:unknown}")
private String appVersion;
@Override
public EdgeInstructions getUpgradeInstructions(TenantId tenantId, Edge edge, String edgeVersion, String upgradeMethod) {
String tbVersion = appVersion.replace("-SNAPSHOT", "");
String currentEdgeVersion = convertEdgeVersionToDocsFormat(edgeVersion);
switch (upgradeMethod.toLowerCase()) {
case "docker":
return getDockerUpgradeInstructions(tenantId, edge.getId(), tbVersion, currentEdgeVersion);
case "ubuntu":
case "centos":
return getLinuxUpgradeInstructions(tenantId, edge.getId(), tbVersion, currentEdgeVersion, upgradeMethod.toLowerCase());
default:
throw new IllegalArgumentException("Unsupported upgrade method for Edge: " + upgradeMethod);
}
}
private EdgeInstructions getDockerUpgradeInstructions(TenantId tenantId, EdgeId edgeId, String tbVersion, String currentEdgeVersion) {
UpgradeInfo upgradeInfo = upgradeVersionHashMap.get(currentEdgeVersion);
if (upgradeInfo.getNextVersion() == null || tbVersion.equals(currentEdgeVersion)) {
return null;
}
boolean stoppedService = false;
StringBuilder result = new StringBuilder(readFile(resolveFile("docker", "upgrade_preparing.md")));
while (upgradeInfo.getNextVersion() != null || !tbVersion.equals(currentEdgeVersion)) {
String edgeVersion = upgradeInfo.getNextVersion();
String ubuntuUpgradeInstructions = readFile(resolveFile("docker", "instructions.md"));
if (upgradeInfo.isUpgradeDb()) {
String upgradeDb = readFile(resolveFile("docker", "upgrade_db.md"));
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${UPGRADE_DB}", upgradeDb);
}
if (!stoppedService) {
stoppedService = true;
String stopService = readFile(resolveFile("docker", "stop_service.md"));
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${STOP_SERVICE}", stopService);
} else {
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${STOP_SERVICE}", "");
}
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${TB_EDGE_VERSION}", edgeVersion + "EDGE");
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${CURRENT_TB_EDGE_VERSION}", currentEdgeVersion + "EDGE");
currentEdgeVersion = edgeVersion;
upgradeInfo = upgradeVersionHashMap.get(upgradeInfo.getNextVersion());
result.append(ubuntuUpgradeInstructions);
}
String startService = readFile(resolveFile("docker", "start_service.md"));
result.append(startService);
AttributeKvEntry attributeKvEntry = new BaseAttributeKvEntry(new StringDataEntry("edgeVersion", currentEdgeVersion), System.currentTimeMillis());
attributesService.save(tenantId, edgeId, DataConstants.SERVER_SCOPE, attributeKvEntry);
return new EdgeInstructions(result.toString());
}
private EdgeInstructions getLinuxUpgradeInstructions(TenantId tenantId, EdgeId edgeId, String tbVersion, String currentEdgeVersion, String os) {
UpgradeInfo upgradeInfo = upgradeVersionHashMap.get(currentEdgeVersion);
if (upgradeInfo.getNextVersion() == null || tbVersion.equals(currentEdgeVersion)) {
return null;
}
boolean stoppedService = false;
StringBuilder result = new StringBuilder(readFile(resolveFile("upgrade_preparing.md")));
while (upgradeInfo.getNextVersion() != null || !tbVersion.equals(currentEdgeVersion)) {
String edgeVersion = upgradeInfo.getNextVersion();
String ubuntuUpgradeInstructions = readFile(resolveFile(os, "instructions.md"));
if (upgradeInfo.isUpgradeDb()) {
String upgradeDb = readFile(resolveFile("upgrade_db.md"));
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${UPGRADE_DB}", upgradeDb);
}
if (!stoppedService) {
stoppedService = true;
String stopService = readFile(resolveFile("stop_service.md"));
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${STOP_SERVICE}", stopService);
} else {
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${STOP_SERVICE}", "");
}
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${TB_EDGE_TAG}", getTagVersion(edgeVersion));
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${CURRENT_TB_EDGE_TAG}", getTagVersion(currentEdgeVersion));
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${CURRENT_TB_EDGE_VERSION}", currentEdgeVersion);
ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${TB_EDGE_VERSION_TITLE}", edgeVersion + "EDGE");
currentEdgeVersion = edgeVersion;
upgradeInfo = upgradeVersionHashMap.get(upgradeInfo.getNextVersion());
result.append(ubuntuUpgradeInstructions);
}
String startService = readFile(resolveFile("start_service.md"));
result.append(startService);
AttributeKvEntry attributeKvEntry = new BaseAttributeKvEntry(new StringDataEntry("edgeVersion", convertDocsFormatToEdgeVersion(currentEdgeVersion)), System.currentTimeMillis());
attributesService.save(tenantId, edgeId, DataConstants.SERVER_SCOPE, attributeKvEntry);
return new EdgeInstructions(result.toString());
}
private String getTagVersion(String version) {
return version.endsWith(".0") ? version.substring(0, version.length() - 2) : version;
}
private String convertEdgeVersionToDocsFormat(String edgeVersion) {
return edgeVersion.replace("_", ".").substring(2);
}
private String convertDocsFormatToEdgeVersion(String edgeVersion) {
return "V_" + edgeVersion.replace(".", "_");
}
private String readFile(Path file) {
try {
return Files.readString(file);
} catch (IOException e) {
log.warn("Failed to read file: {}", file, e);
throw new RuntimeException(e);
}
}
private Path resolveFile(String subDir, String... subDirs) {
return getEdgeInstallInstructionsDir().resolve(Paths.get(subDir, subDirs));
}
private Path getEdgeInstallInstructionsDir() {
return Paths.get(installScripts.getDataDir(), InstallScripts.JSON_DIR, EDGE_DIR, INSTRUCTIONS_DIR, UPGRADE_DIR);
}
@AllArgsConstructor
@Data
public static class UpgradeInfo {
private boolean upgradeDb;
private String nextVersion;
}
}

View File

@ -16,12 +16,12 @@
package org.thingsboard.server.service.edge.instructions; package org.thingsboard.server.service.edge.instructions;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInstallInstructions; import org.thingsboard.server.common.data.edge.EdgeInstructions;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
public interface EdgeInstallService { public interface EdgeInstallService {
EdgeInstallInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request); EdgeInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request);
} }

View File

@ -0,0 +1,25 @@
/**
* Copyright © 2016-2023 The Thingsboard 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 org.thingsboard.server.service.edge.instructions;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInstructions;
import org.thingsboard.server.common.data.id.TenantId;
public interface EdgeUpgradeService {
EdgeInstructions getUpgradeInstructions(TenantId tenantId, Edge edge, String edgeVersion, String upgradeMethod) throws Exception;
}

View File

@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.SortOrder;
@ -774,7 +775,7 @@ public final class EdgeGrpcSession implements Closeable {
try { try {
if (edge.getSecret().equals(request.getEdgeSecret())) { if (edge.getSecret().equals(request.getEdgeSecret())) {
sessionOpenListener.accept(edge.getId(), this); sessionOpenListener.accept(edge.getId(), this);
this.edgeVersion = request.getEdgeVersion(); this.edgeVersion = processGetAndSaveEdgeVersion(request.getEdgeVersion());
return ConnectResponseMsg.newBuilder() return ConnectResponseMsg.newBuilder()
.setResponseCode(ConnectResponseCode.ACCEPTED) .setResponseCode(ConnectResponseCode.ACCEPTED)
.setErrorMsg("") .setErrorMsg("")
@ -800,6 +801,12 @@ public final class EdgeGrpcSession implements Closeable {
.setConfiguration(EdgeConfiguration.getDefaultInstance()).build(); .setConfiguration(EdgeConfiguration.getDefaultInstance()).build();
} }
private EdgeVersion processGetAndSaveEdgeVersion(EdgeVersion edgeVersion) {
AttributeKvEntry attributeKvEntry = new BaseAttributeKvEntry(new StringDataEntry("edgeVersion", edgeVersion.name()), System.currentTimeMillis());
ctx.getAttributesService().save(this.tenantId, this.edge.getId(), DataConstants.SERVER_SCOPE, attributeKvEntry);
return edgeVersion;
}
@Override @Override
public void close() { public void close() {
log.debug("[{}][{}] Closing session", this.tenantId, sessionId); log.debug("[{}][{}] Closing session", this.tenantId, sessionId);

View File

@ -25,8 +25,8 @@ import lombok.NoArgsConstructor;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class EdgeInstallInstructions { public class EdgeInstructions {
@ApiModelProperty(position = 1, value = "Markdown with install instructions") @ApiModelProperty(position = 1, value = "Markdown with install/upgrade instructions")
private String installInstructions; private String instructions;
} }

View File

@ -84,7 +84,7 @@ import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeInfo; import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeInstallInstructions; import org.thingsboard.server.common.data.edge.EdgeInstructions;
import org.thingsboard.server.common.data.edge.EdgeSearchQuery; import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
@ -3241,9 +3241,9 @@ public class RestClient implements Closeable {
}).getBody(); }).getBody();
} }
public Optional<EdgeInstallInstructions> getEdgeDockerInstallInstructions(EdgeId edgeId) { public Optional<EdgeInstructions> getEdgeDockerInstallInstructions(EdgeId edgeId, String method) {
ResponseEntity<EdgeInstallInstructions> edgeInstallInstructionsResult = ResponseEntity<EdgeInstructions> edgeInstallInstructionsResult =
restTemplate.getForEntity(baseURL + "/api/edge/instructions/{edgeId}", EdgeInstallInstructions.class, edgeId.getId()); restTemplate.getForEntity(baseURL + "/api/edge/instructions/install/{edgeId}/{method}", EdgeInstructions.class, edgeId.getId(), method);
return Optional.ofNullable(edgeInstallInstructionsResult.getBody()); return Optional.ofNullable(edgeInstallInstructionsResult.getBody());
} }