Introduce edge upgrade documentation
This commit is contained in:
		
							parent
							
								
									3c90b9cf2f
								
							
						
					
					
						commit
						deeb0208a9
					
				@ -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
 | 
			
		||||
Before continue to installation execute the following commands in order to install necessary tools:
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
ThingsBoard service is running on Java 11. Follow these instructions to install OpenJDK 11:
 | 
			
		||||
@ -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}
 | 
			
		||||
```
 | 
			
		||||
@ -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}.
 | 
			
		||||
@ -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}
 | 
			
		||||
```
 | 
			
		||||
@ -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 it’s still running):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
make <span style="color:red;">docker-compose.yml</span>
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
docker compose stop
 | 
			
		||||
docker compose rm mytbedge
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
@ -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}
 | 
			
		||||
```
 | 
			
		||||
@ -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>
 | 
			
		||||
@ -0,0 +1,6 @@
 | 
			
		||||
Start the service
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo service tb-edge start
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
@ -0,0 +1,6 @@
 | 
			
		||||
Stop ThingsBoard Edge service if it is running:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo service tb-edge stop
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
@ -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}
 | 
			
		||||
@ -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}
 | 
			
		||||
```
 | 
			
		||||
@ -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.
 | 
			
		||||
@ -39,7 +39,7 @@ import org.thingsboard.server.common.data.Customer;
 | 
			
		||||
import org.thingsboard.server.common.data.EntitySubtype;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.Edge;
 | 
			
		||||
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.exception.ThingsboardErrorCode;
 | 
			
		||||
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.service.edge.EdgeBulkImportService;
 | 
			
		||||
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.entitiy.edge.TbEdgeService;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
@ -102,6 +103,7 @@ public class EdgeController extends BaseController {
 | 
			
		||||
    private final TbEdgeService tbEdgeService;
 | 
			
		||||
    private final Optional<EdgeRpcService> edgeRpcServiceOpt;
 | 
			
		||||
    private final Optional<EdgeInstallService> edgeInstallServiceOpt;
 | 
			
		||||
    private final Optional<EdgeUpgradeService> edgeUpgradeServiceOpt;
 | 
			
		||||
 | 
			
		||||
    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. " +
 | 
			
		||||
@ -553,16 +555,16 @@ public class EdgeController extends BaseController {
 | 
			
		||||
        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,
 | 
			
		||||
            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
 | 
			
		||||
    @RequestMapping(value = "/edge/instructions/{edgeId}/{method}", method = RequestMethod.GET)
 | 
			
		||||
    @RequestMapping(value = "/edge/instructions/install/{edgeId}/{method}", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public EdgeInstallInstructions getEdgeDockerInstallInstructions(
 | 
			
		||||
    public EdgeInstructions getEdgeInstallInstructions(
 | 
			
		||||
            @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true)
 | 
			
		||||
            @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,
 | 
			
		||||
            HttpServletRequest request) throws ThingsboardException {
 | 
			
		||||
        if (isEdgesEnabled() && edgeInstallServiceOpt.isPresent()) {
 | 
			
		||||
@ -574,4 +576,27 @@ public class EdgeController extends BaseController {
 | 
			
		||||
            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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ 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.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.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.install.InstallScripts;
 | 
			
		||||
@ -40,8 +40,8 @@ import java.nio.file.Paths;
 | 
			
		||||
public class DefaultEdgeInstallService implements EdgeInstallService {
 | 
			
		||||
 | 
			
		||||
    private static final String EDGE_DIR = "edge";
 | 
			
		||||
 | 
			
		||||
    private static final String EDGE_INSTALL_INSTRUCTIONS_DIR = "install_instructions";
 | 
			
		||||
    private static final String INSTRUCTIONS_DIR = "instructions";
 | 
			
		||||
    private static final String INSTALL_DIR = "install";
 | 
			
		||||
 | 
			
		||||
    private final InstallScripts installScripts;
 | 
			
		||||
 | 
			
		||||
@ -55,7 +55,7 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
 | 
			
		||||
    private String appVersion;
 | 
			
		||||
 | 
			
		||||
    @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()) {
 | 
			
		||||
            case "docker":
 | 
			
		||||
                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 baseUrl = request.getServerName();
 | 
			
		||||
        if (baseUrl.contains("localhost") || baseUrl.contains("127.0.0.1")) {
 | 
			
		||||
@ -83,26 +83,26 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
 | 
			
		||||
        edgeVersion = edgeVersion.replace("-SNAPSHOT", "");
 | 
			
		||||
        dockerInstallInstructions = dockerInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
 | 
			
		||||
        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"));
 | 
			
		||||
        ubuntuInstallInstructions = replacePlaceholders(ubuntuInstallInstructions, edge);
 | 
			
		||||
        ubuntuInstallInstructions = ubuntuInstallInstructions.replace("${BASE_URL}", request.getServerName());
 | 
			
		||||
        String edgeVersion = appVersion.replace("-SNAPSHOT", "");
 | 
			
		||||
        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"));
 | 
			
		||||
        centosInstallInstructions = replacePlaceholders(centosInstallInstructions, edge);
 | 
			
		||||
        centosInstallInstructions = centosInstallInstructions.replace("${BASE_URL}", request.getServerName());
 | 
			
		||||
        String edgeVersion = appVersion.replace("-SNAPSHOT", "");
 | 
			
		||||
        centosInstallInstructions = centosInstallInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
 | 
			
		||||
        return new EdgeInstallInstructions(centosInstallInstructions);
 | 
			
		||||
        return new EdgeInstructions(centosInstallInstructions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String replacePlaceholders(String instructions, Edge edge) {
 | 
			
		||||
@ -127,6 +127,6 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -16,12 +16,12 @@
 | 
			
		||||
package org.thingsboard.server.service.edge.instructions;
 | 
			
		||||
 | 
			
		||||
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 javax.servlet.http.HttpServletRequest;
 | 
			
		||||
 | 
			
		||||
public interface EdgeInstallService {
 | 
			
		||||
 | 
			
		||||
    EdgeInstallInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request);
 | 
			
		||||
    EdgeInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
@ -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.BaseAttributeKvEntry;
 | 
			
		||||
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.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.page.SortOrder;
 | 
			
		||||
@ -774,7 +775,7 @@ public final class EdgeGrpcSession implements Closeable {
 | 
			
		||||
            try {
 | 
			
		||||
                if (edge.getSecret().equals(request.getEdgeSecret())) {
 | 
			
		||||
                    sessionOpenListener.accept(edge.getId(), this);
 | 
			
		||||
                    this.edgeVersion = request.getEdgeVersion();
 | 
			
		||||
                    this.edgeVersion = processGetAndSaveEdgeVersion(request.getEdgeVersion());
 | 
			
		||||
                    return ConnectResponseMsg.newBuilder()
 | 
			
		||||
                            .setResponseCode(ConnectResponseCode.ACCEPTED)
 | 
			
		||||
                            .setErrorMsg("")
 | 
			
		||||
@ -800,6 +801,12 @@ public final class EdgeGrpcSession implements Closeable {
 | 
			
		||||
                .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
 | 
			
		||||
    public void close() {
 | 
			
		||||
        log.debug("[{}][{}] Closing session", this.tenantId, sessionId);
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,8 @@ import lombok.NoArgsConstructor;
 | 
			
		||||
@Data
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
public class EdgeInstallInstructions {
 | 
			
		||||
public class EdgeInstructions {
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(position = 1, value = "Markdown with install instructions")
 | 
			
		||||
    private String installInstructions;
 | 
			
		||||
    @ApiModelProperty(position = 1, value = "Markdown with install/upgrade instructions")
 | 
			
		||||
    private String instructions;
 | 
			
		||||
}
 | 
			
		||||
@ -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.EdgeEvent;
 | 
			
		||||
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.entityview.EntityViewSearchQuery;
 | 
			
		||||
import org.thingsboard.server.common.data.id.AlarmCommentId;
 | 
			
		||||
@ -3241,9 +3241,9 @@ public class RestClient implements Closeable {
 | 
			
		||||
                }).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<EdgeInstallInstructions> getEdgeDockerInstallInstructions(EdgeId edgeId) {
 | 
			
		||||
        ResponseEntity<EdgeInstallInstructions> edgeInstallInstructionsResult =
 | 
			
		||||
                restTemplate.getForEntity(baseURL + "/api/edge/instructions/{edgeId}", EdgeInstallInstructions.class, edgeId.getId());
 | 
			
		||||
    public Optional<EdgeInstructions> getEdgeDockerInstallInstructions(EdgeId edgeId, String method) {
 | 
			
		||||
        ResponseEntity<EdgeInstructions> edgeInstallInstructionsResult =
 | 
			
		||||
                restTemplate.getForEntity(baseURL + "/api/edge/instructions/install/{edgeId}/{method}", EdgeInstructions.class, edgeId.getId(), method);
 | 
			
		||||
        return Optional.ofNullable(edgeInstallInstructionsResult.getBody());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user