Merge pull request #9688 from AndriiLandiak/edge-upgrade-instructions
Edge upgrade instructions
This commit is contained in:
commit
4c3e081b91
@ -1,3 +0,0 @@
|
||||
###### WARNING NOTE: 'localhost' can not be used as CLOUD_RPC_HOST
|
||||
|
||||
Please note that your ThingsBoard base URL is **'localhost'** at the moment. **'localhost'** cannot be used for docker containers - please update **CLOUD_RPC_HOST** environment variable below to the IP address of your machine (*docker **host** machine*). IP address must be `192.168.1.XX` or similar format. In other case - ThingsBoard Edge service, that is running in docker container, will not be able to connect to the cloud.
|
||||
@ -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:
|
||||
@ -56,13 +56,13 @@ sudo yum update
|
||||
sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
|
||||
# Install packages
|
||||
sudo yum -y install epel-release yum-utils
|
||||
sudo yum-config-manager --enable pgdg12
|
||||
sudo yum install postgresql12-server postgresql12
|
||||
sudo yum-config-manager --enable pgdg15
|
||||
sudo yum install postgresql15-server postgresql15
|
||||
# Initialize your PostgreSQL DB
|
||||
sudo /usr/pgsql-12/bin/postgresql-12-setup initdb
|
||||
sudo systemctl start postgresql-12
|
||||
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
|
||||
sudo systemctl start postgresql-15
|
||||
# Optional: Configure PostgreSQL to start on boot
|
||||
sudo systemctl enable --now postgresql-12
|
||||
sudo systemctl enable --now postgresql-15
|
||||
|
||||
{:copy-code}
|
||||
```
|
||||
@ -74,12 +74,12 @@ sudo systemctl enable --now postgresql-12
|
||||
sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
|
||||
# Install packages
|
||||
sudo dnf -qy module disable postgresql
|
||||
sudo dnf -y install postgresql12 postgresql12-server
|
||||
sudo dnf -y install postgresql15 postgresql15-server
|
||||
# Initialize your PostgreSQL DB
|
||||
sudo /usr/pgsql-12/bin/postgresql-12-setup initdb
|
||||
sudo systemctl start postgresql-12
|
||||
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
|
||||
sudo systemctl start postgresql-15
|
||||
# Optional: Configure PostgreSQL to start on boot
|
||||
sudo systemctl enable --now postgresql-12
|
||||
sudo systemctl enable --now postgresql-15
|
||||
|
||||
{:copy-code}
|
||||
```
|
||||
@ -101,7 +101,7 @@ After configuring the password, edit the pg_hba.conf to use MD5 authentication w
|
||||
Edit pg_hba.conf file:
|
||||
|
||||
```bash
|
||||
sudo nano /var/lib/pgsql/12/data/pg_hba.conf
|
||||
sudo nano /var/lib/pgsql/15/data/pg_hba.conf
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
@ -121,7 +121,7 @@ host all all 127.0.0.1/32 md5
|
||||
Finally, you should restart the PostgreSQL service to initialize the new configuration:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart postgresql-12.service
|
||||
sudo systemctl restart postgresql-15.service
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
@ -1,25 +1,11 @@
|
||||
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
|
||||
|
||||
Install <a href="https://docs.docker.com/engine/install/" target="_blank"> Docker CE</a> and <a href="https://docs.docker.com/compose/install/" target="_blank"> Docker Compose</a>.
|
||||
|
||||
#### Create data and logs folders
|
||||
|
||||
Run following commands, before starting docker container(s), to create folders for storing data and logs.
|
||||
These commands additionally will change owner of newly created folders to docker container user.
|
||||
To do this (to change user) **chown** command is used, and this command requires *sudo* permissions (command will request password for a *sudo* access):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.mytb-edge-data && sudo chown -R 799:799 ~/.mytb-edge-data
|
||||
mkdir -p ~/.mytb-edge-logs && sudo chown -R 799:799 ~/.mytb-edge-logs
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
#### Running ThingsBoard Edge as docker service
|
||||
|
||||
${LOCALHOST_WARNING}
|
||||
|
||||
Create docker compose file for ThingsBoard Edge service:
|
||||
|
||||
```bash
|
||||
@ -30,7 +16,7 @@ nano docker-compose.yml
|
||||
Add the following lines to the yml file:
|
||||
|
||||
```bash
|
||||
version: '3.0'
|
||||
version: '3.8'
|
||||
services:
|
||||
mytbedge:
|
||||
restart: always
|
||||
@ -47,8 +33,9 @@ services:
|
||||
CLOUD_RPC_PORT: ${CLOUD_RPC_PORT}
|
||||
CLOUD_RPC_SSL_ENABLED: ${CLOUD_RPC_SSL_ENABLED}
|
||||
volumes:
|
||||
- ~/.mytb-edge-data:/data
|
||||
- ~/.mytb-edge-logs:/var/log/tb-edge
|
||||
- tb-edge-data:/data
|
||||
- tb-edge-logs:/var/log/tb-edge
|
||||
${EXTRA_HOSTS}
|
||||
postgres:
|
||||
restart: always
|
||||
image: "postgres:15"
|
||||
@ -58,7 +45,15 @@ services:
|
||||
POSTGRES_DB: tb-edge
|
||||
POSTGRES_PASSWORD: postgres
|
||||
volumes:
|
||||
- ~/.mytb-edge-data/db:/var/lib/postgresql/data
|
||||
- tb-edge-postgres-data:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
tb-edge-data:
|
||||
name: tb-edge-data
|
||||
tb-edge-logs:
|
||||
name: tb-edge-logs
|
||||
tb-edge-postgres-data:
|
||||
name: tb-edge-postgres-data
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
@ -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:
|
||||
@ -49,7 +49,7 @@ echo "deb http://apt.postgresql.org/pub/repos/apt/ ${RELEASE}"-pgdg main | sudo
|
||||
|
||||
# install and launch the postgresql service:
|
||||
sudo apt update
|
||||
sudo apt -y install postgresql-12
|
||||
sudo apt -y install postgresql-15
|
||||
sudo service postgresql start
|
||||
{:copy-code}
|
||||
```
|
||||
@ -0,0 +1,15 @@
|
||||
#### Upgrading to ${TB_EDGE_VERSION}EDGE
|
||||
|
||||
**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
|
||||
|
||||
Install package:
|
||||
```bash
|
||||
sudo rpm -Uvh tb-edge-${TB_EDGE_TAG}.rpm
|
||||
{:copy-code}
|
||||
```
|
||||
${UPGRADE_DB}
|
||||
@ -0,0 +1,10 @@
|
||||
#### Upgrading to ${TB_EDGE_VERSION}
|
||||
|
||||
Execute the following command to pull **${TB_EDGE_VERSION}** image:
|
||||
|
||||
```bash
|
||||
docker pull thingsboard/tb-edge:${TB_EDGE_VERSION}
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
${UPGRADE_DB}
|
||||
@ -0,0 +1,23 @@
|
||||
Modify ‘main’ docker compose (`docker-compose.yml`) file for ThingsBoard Edge and update version of the image:
|
||||
```bash
|
||||
nano docker-compose.yml
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
```text
|
||||
version: '3.8'
|
||||
services:
|
||||
mytbedge:
|
||||
restart: always
|
||||
image: "thingsboard/tb-edge:${TB_EDGE_VERSION}"
|
||||
...
|
||||
```
|
||||
|
||||
Make sure your image is the set to **tb-edge-${TB_EDGE_VERSION}**.
|
||||
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,61 @@
|
||||
Create docker compose file for ThingsBoard Edge upgrade process:
|
||||
|
||||
```bash
|
||||
> docker-compose-upgrade.yml && nano docker-compose-upgrade.yml
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
Add the following lines to the yml file:
|
||||
|
||||
```bash
|
||||
version: '3.8'
|
||||
services:
|
||||
mytbedge:
|
||||
restart: on-failure
|
||||
image: "thingsboard/tb-edge:${TB_EDGE_VERSION}"
|
||||
environment:
|
||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/tb-edge
|
||||
volumes:
|
||||
- tb-edge-data:/data
|
||||
- tb-edge-logs:/var/log/tb-edge
|
||||
entrypoint: upgrade-tb-edge.sh
|
||||
postgres:
|
||||
restart: always
|
||||
image: "postgres:15"
|
||||
ports:
|
||||
- "5432"
|
||||
environment:
|
||||
POSTGRES_DB: tb-edge
|
||||
POSTGRES_PASSWORD: postgres
|
||||
volumes:
|
||||
- tb-edge-postgres-data:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
tb-edge-data:
|
||||
name: tb-edge-data
|
||||
tb-edge-logs:
|
||||
name: tb-edge-logs
|
||||
tb-edge-postgres-data:
|
||||
name: tb-edge-postgres-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,83 @@
|
||||
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}
|
||||
```
|
||||
|
||||
**OPTIONAL:** If you still rely on Docker Compose as docker-compose (with a hyphen) here is the list of the above commands:
|
||||
```text
|
||||
docker-compose stop
|
||||
docker-compose rm mytbedge
|
||||
```
|
||||
|
||||
##### Migrating Data from Docker Bind Mount Folders to Docker Volumes
|
||||
Starting with the **3.6.2** release, the ThingsBoard team has transitioned from using Docker bind mount folders to Docker volumes.
|
||||
This change aims to enhance security and efficiency in storing data for Docker containers and to mitigate permission issues across various environments.
|
||||
|
||||
To migrate from Docker bind mounts to Docker volumes, please execute the following commands:
|
||||
|
||||
```bash
|
||||
docker run --rm -v tb-edge-data:/volume -v ~/.mytb-edge-data:/backup busybox sh -c "cp -a /backup/. /volume"
|
||||
docker run --rm -v tb-edge-logs:/volume -v ~/.mytb-edge-logs:/backup busybox sh -c "cp -a /backup/. /volume"
|
||||
docker run --rm -v tb-edge-postgres-data:/volume -v ~/.mytb-edge-data/db:/backup busybox sh -c "cp -a /backup/. /volume"
|
||||
{:copy-code}
|
||||
```
|
||||
|
||||
After completing the data migration to the newly created Docker volumes, you'll need to update the volume mounts in your Docker Compose configuration.
|
||||
Modify the `docker-compose.yml` file for ThingsBoard Edge to update the volume settings.
|
||||
|
||||
First, please update docker compose file version. Find next snippet:
|
||||
```text
|
||||
version: '3.0'
|
||||
...
|
||||
```
|
||||
|
||||
And replace it with:
|
||||
```text
|
||||
version: '3.8'
|
||||
...
|
||||
```
|
||||
|
||||
Then update volume mounts. Locate the following snippet:
|
||||
```text
|
||||
volumes:
|
||||
- ~/.mytb-edge-data:/data
|
||||
- ~/.mytb-edge-logs:/var/log/tb-edge
|
||||
...
|
||||
```
|
||||
|
||||
And replace it with:
|
||||
```text
|
||||
volumes:
|
||||
- tb-edge-data:/data
|
||||
- tb-edge-logs:/var/log/tb-edge
|
||||
...
|
||||
```
|
||||
|
||||
Apply a similar update for the PostgreSQL service. Find the section:
|
||||
```text
|
||||
volumes:
|
||||
- ~/.mytb-edge-data/db:/var/lib/postgresql/data
|
||||
...
|
||||
```
|
||||
|
||||
And replace it with:
|
||||
```text
|
||||
volumes:
|
||||
- tb-edge-postgres-data/:/var/lib/postgresql/data
|
||||
...
|
||||
```
|
||||
|
||||
##### Backup Database
|
||||
Make a copy of the database volume before upgrading:
|
||||
|
||||
```bash
|
||||
docker run --rm -v tb-edge-postgres-data:/source -v tb-edge-postgres-data-backup:/backup busybox sh -c "cp -a /source/. /backup"
|
||||
{:copy-code}
|
||||
```
|
||||
@ -0,0 +1,6 @@
|
||||
Start the service
|
||||
|
||||
```bash
|
||||
sudo systemctl tb-edge start
|
||||
{:copy-code}
|
||||
```
|
||||
@ -0,0 +1,15 @@
|
||||
#### Upgrading to ${TB_EDGE_VERSION}EDGE
|
||||
|
||||
**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
|
||||
|
||||
Install package:
|
||||
```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=${FROM_TB_EDGE_VERSION}
|
||||
{:copy-code}
|
||||
```
|
||||
@ -0,0 +1,36 @@
|
||||
Here is the list of commands, that can be used to quickly upgrade ThingsBoard Edge on ${OS}
|
||||
|
||||
#### 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;
|
||||
@ -59,7 +59,8 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
|
||||
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.EdgeInstallInstructionsService;
|
||||
import org.thingsboard.server.service.edge.instructions.EdgeUpgradeInstructionsService;
|
||||
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
|
||||
import org.thingsboard.server.service.entitiy.edge.TbEdgeService;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
@ -101,7 +102,8 @@ public class EdgeController extends BaseController {
|
||||
private final EdgeBulkImportService edgeBulkImportService;
|
||||
private final TbEdgeService tbEdgeService;
|
||||
private final Optional<EdgeRpcService> edgeRpcServiceOpt;
|
||||
private final Optional<EdgeInstallService> edgeInstallServiceOpt;
|
||||
private final Optional<EdgeInstallInstructionsService> edgeInstallServiceOpt;
|
||||
private final Optional<EdgeUpgradeInstructionsService> 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,23 +555,41 @@ public class EdgeController extends BaseController {
|
||||
return edgeBulkImportService.processBulkImport(request, user);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Get Edge Docker Install Instructions (getEdgeDockerInstallInstructions)",
|
||||
notes = "Get a docker install instructions for provided edge id." + TENANT_AUTHORITY_PARAGRAPH,
|
||||
@ApiOperation(value = "Get Edge Install Instructions (getEdgeInstallInstructions)",
|
||||
notes = "Get an 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()) {
|
||||
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
|
||||
edgeId = checkNotNull(edgeId);
|
||||
Edge edge = checkEdgeId(edgeId, Operation.READ);
|
||||
return checkNotNull(edgeInstallServiceOpt.get().getInstallInstructions(getTenantId(), edge, installationMethod, request));
|
||||
return checkNotNull(edgeInstallServiceOpt.get().getInstallInstructions(edge, installationMethod, request));
|
||||
} else {
|
||||
throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Get Edge Upgrade Instructions (getEdgeUpgradeInstructions)",
|
||||
notes = "Get an upgrade instructions for provided edge version." + TENANT_AUTHORITY_PARAGRAPH,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
|
||||
@RequestMapping(value = "/edge/instructions/upgrade/{edgeVersion}/{method}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public EdgeInstructions getEdgeUpgradeInstructions(
|
||||
@ApiParam(value = "Edge version", required = true)
|
||||
@PathVariable("edgeVersion") String edgeVersion,
|
||||
@ApiParam(value = "Upgrade method ('docker', 'ubuntu' or 'centos')", allowableValues = "docker, ubuntu, centos")
|
||||
@PathVariable("method") String method) throws Exception {
|
||||
if (isEdgesEnabled() && edgeUpgradeServiceOpt.isPresent()) {
|
||||
return checkNotNull(edgeUpgradeServiceOpt.get().getUpgradeInstructions(edgeVersion, method));
|
||||
} else {
|
||||
throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
|
||||
}
|
||||
|
||||
@ -16,13 +16,14 @@
|
||||
package org.thingsboard.server.service.edge.instructions;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
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.edge.Edge;
|
||||
import org.thingsboard.server.common.data.edge.EdgeInstallInstructions;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.edge.EdgeInstructions;
|
||||
import org.thingsboard.server.dao.util.DeviceConnectivityUtil;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.install.InstallScripts;
|
||||
|
||||
@ -37,11 +38,11 @@ import java.nio.file.Paths;
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true")
|
||||
@TbCoreComponent
|
||||
public class DefaultEdgeInstallService implements EdgeInstallService {
|
||||
public class DefaultEdgeInstallInstructionsService implements EdgeInstallInstructionsService {
|
||||
|
||||
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;
|
||||
|
||||
@ -52,10 +53,11 @@ public class DefaultEdgeInstallService implements EdgeInstallService {
|
||||
private boolean sslEnabled;
|
||||
|
||||
@Value("${app.version:unknown}")
|
||||
@Setter
|
||||
private String appVersion;
|
||||
|
||||
@Override
|
||||
public EdgeInstallInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request) {
|
||||
public EdgeInstructions getInstallInstructions(Edge edge, String installationMethod, HttpServletRequest request) {
|
||||
switch (installationMethod.toLowerCase()) {
|
||||
case "docker":
|
||||
return getDockerInstallInstructions(edge, request);
|
||||
@ -68,41 +70,41 @@ 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")) {
|
||||
String localhostWarning = readFile(resolveFile("docker", "localhost_warning.md"));
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${LOCALHOST_WARNING}", localhostWarning);
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${BASE_URL}", "!!!REPLACE_ME_TO_HOST_IP_ADDRESS!!!");
|
||||
|
||||
if (DeviceConnectivityUtil.isLocalhost(baseUrl)) {
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${EXTRA_HOSTS}", "extra_hosts:\n - \"host.docker.internal:host-gateway\"\n");
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${BASE_URL}", "host.docker.internal");
|
||||
} else {
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${LOCALHOST_WARNING}", "");
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${EXTRA_HOSTS}", "");
|
||||
dockerInstallInstructions = dockerInstallInstructions.replace("${BASE_URL}", baseUrl);
|
||||
}
|
||||
String edgeVersion = appVersion + "EDGE";
|
||||
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 +129,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,158 @@
|
||||
/**
|
||||
* 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.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
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.EdgeUpgradeInfo;
|
||||
import org.thingsboard.server.common.data.edge.EdgeInstructions;
|
||||
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;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true")
|
||||
@TbCoreComponent
|
||||
public class DefaultEdgeUpgradeInstructionsService implements EdgeUpgradeInstructionsService {
|
||||
|
||||
private static final Map<String, EdgeUpgradeInfo> upgradeVersionHashMap = new HashMap<>();
|
||||
|
||||
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;
|
||||
|
||||
@Value("${app.version:unknown}")
|
||||
@Setter
|
||||
private String appVersion;
|
||||
|
||||
@Override
|
||||
public EdgeInstructions getUpgradeInstructions(String edgeVersion, String upgradeMethod) {
|
||||
String tbVersion = appVersion.replace("-SNAPSHOT", "");
|
||||
String currentEdgeVersion = convertEdgeVersionToDocsFormat(edgeVersion);
|
||||
switch (upgradeMethod.toLowerCase()) {
|
||||
case "docker":
|
||||
return getDockerUpgradeInstructions(tbVersion, currentEdgeVersion);
|
||||
case "ubuntu":
|
||||
case "centos":
|
||||
return getLinuxUpgradeInstructions(tbVersion, currentEdgeVersion, upgradeMethod.toLowerCase());
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported upgrade method for Edge: " + upgradeMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInstructionMap(Map<String, EdgeUpgradeInfo> map) {
|
||||
for (String key : map.keySet()) {
|
||||
upgradeVersionHashMap.put(key, map.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
private EdgeInstructions getDockerUpgradeInstructions(String tbVersion, String currentEdgeVersion) {
|
||||
EdgeUpgradeInfo edgeUpgradeInfo = upgradeVersionHashMap.get(currentEdgeVersion);
|
||||
if (edgeUpgradeInfo == null || edgeUpgradeInfo.getNextEdgeVersion() == null || tbVersion.equals(currentEdgeVersion)) {
|
||||
return new EdgeInstructions("Edge upgrade instruction for " + currentEdgeVersion + "EDGE is not available.");
|
||||
}
|
||||
StringBuilder result = new StringBuilder(readFile(resolveFile("docker", "upgrade_preparing.md")));
|
||||
while (edgeUpgradeInfo.getNextEdgeVersion() != null || !tbVersion.equals(currentEdgeVersion)) {
|
||||
String edgeVersion = edgeUpgradeInfo.getNextEdgeVersion();
|
||||
String dockerUpgradeInstructions = readFile(resolveFile("docker", "instructions.md"));
|
||||
if (edgeUpgradeInfo.isRequiresUpdateDb()) {
|
||||
String upgradeDb = readFile(resolveFile("docker", "upgrade_db.md"));
|
||||
dockerUpgradeInstructions = dockerUpgradeInstructions.replace("${UPGRADE_DB}", upgradeDb);
|
||||
} else {
|
||||
dockerUpgradeInstructions = dockerUpgradeInstructions.replace("${UPGRADE_DB}", "");
|
||||
}
|
||||
dockerUpgradeInstructions = dockerUpgradeInstructions.replace("${TB_EDGE_VERSION}", edgeVersion + "EDGE");
|
||||
dockerUpgradeInstructions = dockerUpgradeInstructions.replace("${FROM_TB_EDGE_VERSION}", currentEdgeVersion + "EDGE");
|
||||
currentEdgeVersion = edgeVersion;
|
||||
edgeUpgradeInfo = upgradeVersionHashMap.get(edgeUpgradeInfo.getNextEdgeVersion());
|
||||
result.append(dockerUpgradeInstructions);
|
||||
}
|
||||
String startService = readFile(resolveFile("docker", "start_service.md"));
|
||||
startService = startService.replace("${TB_EDGE_VERSION}", currentEdgeVersion + "EDGE");
|
||||
result.append(startService);
|
||||
return new EdgeInstructions(result.toString());
|
||||
}
|
||||
|
||||
private EdgeInstructions getLinuxUpgradeInstructions(String tbVersion, String currentEdgeVersion, String os) {
|
||||
EdgeUpgradeInfo edgeUpgradeInfo = upgradeVersionHashMap.get(currentEdgeVersion);
|
||||
if (edgeUpgradeInfo == null || edgeUpgradeInfo.getNextEdgeVersion() == null || tbVersion.equals(currentEdgeVersion)) {
|
||||
return new EdgeInstructions("Edge upgrade instruction for " + currentEdgeVersion + "EDGE is not available.");
|
||||
}
|
||||
String upgrade_preparing = readFile(resolveFile("upgrade_preparing.md"));
|
||||
upgrade_preparing = upgrade_preparing.replace("${OS}", os.equals("centos") ? "RHEL/CentOS 7/8" : "Ubuntu");
|
||||
StringBuilder result = new StringBuilder(upgrade_preparing);
|
||||
while (edgeUpgradeInfo.getNextEdgeVersion() != null || !tbVersion.equals(currentEdgeVersion)) {
|
||||
String edgeVersion = edgeUpgradeInfo.getNextEdgeVersion();
|
||||
String linuxUpgradeInstructions = readFile(resolveFile(os, "instructions.md"));
|
||||
if (edgeUpgradeInfo.isRequiresUpdateDb()) {
|
||||
String upgradeDb = readFile(resolveFile("upgrade_db.md"));
|
||||
linuxUpgradeInstructions = linuxUpgradeInstructions.replace("${UPGRADE_DB}", upgradeDb);
|
||||
} else {
|
||||
linuxUpgradeInstructions = linuxUpgradeInstructions.replace("${UPGRADE_DB}", "");
|
||||
}
|
||||
linuxUpgradeInstructions = linuxUpgradeInstructions.replace("${TB_EDGE_TAG}", getTagVersion(edgeVersion));
|
||||
linuxUpgradeInstructions = linuxUpgradeInstructions.replace("${FROM_TB_EDGE_TAG}", getTagVersion(currentEdgeVersion));
|
||||
linuxUpgradeInstructions = linuxUpgradeInstructions.replace("${TB_EDGE_VERSION}", edgeVersion);
|
||||
linuxUpgradeInstructions = linuxUpgradeInstructions.replace("${FROM_TB_EDGE_VERSION}", currentEdgeVersion);
|
||||
currentEdgeVersion = edgeVersion;
|
||||
edgeUpgradeInfo = upgradeVersionHashMap.get(edgeUpgradeInfo.getNextEdgeVersion());
|
||||
result.append(linuxUpgradeInstructions);
|
||||
}
|
||||
String startService = readFile(resolveFile("start_service.md"));
|
||||
result.append(startService);
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
@ -16,12 +16,13 @@
|
||||
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.id.TenantId;
|
||||
import org.thingsboard.server.common.data.edge.EdgeInstructions;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface EdgeInstallService {
|
||||
public interface EdgeInstallInstructionsService {
|
||||
|
||||
EdgeInstallInstructions getInstallInstructions(TenantId tenantId, Edge edge, String installationMethod, HttpServletRequest request);
|
||||
EdgeInstructions getInstallInstructions(Edge edge, String installationMethod, HttpServletRequest request);
|
||||
|
||||
void setAppVersion(String version);
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.EdgeUpgradeInfo;
|
||||
import org.thingsboard.server.common.data.edge.EdgeInstructions;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface EdgeUpgradeInstructionsService {
|
||||
|
||||
EdgeInstructions getUpgradeInstructions(String edgeVersion, String upgradeMethod);
|
||||
|
||||
void updateInstructionMap(Map<String, EdgeUpgradeInfo> upgradeVersions);
|
||||
|
||||
void setAppVersion(String version);
|
||||
}
|
||||
@ -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;
|
||||
@ -794,6 +795,7 @@ public final class EdgeGrpcSession implements Closeable {
|
||||
if (edge.getSecret().equals(request.getEdgeSecret())) {
|
||||
sessionOpenListener.accept(edge.getId(), this);
|
||||
this.edgeVersion = request.getEdgeVersion();
|
||||
processSaveEdgeVersionAsAttribute(request.getEdgeVersion().name());
|
||||
return ConnectResponseMsg.newBuilder()
|
||||
.setResponseCode(ConnectResponseCode.ACCEPTED)
|
||||
.setErrorMsg("")
|
||||
@ -819,6 +821,11 @@ public final class EdgeGrpcSession implements Closeable {
|
||||
.setConfiguration(EdgeConfiguration.getDefaultInstance()).build();
|
||||
}
|
||||
|
||||
private void processSaveEdgeVersionAsAttribute(String edgeVersion) {
|
||||
AttributeKvEntry attributeKvEntry = new BaseAttributeKvEntry(new StringDataEntry("edgeVersion", edgeVersion), System.currentTimeMillis());
|
||||
ctx.getAttributesService().save(this.tenantId, this.edge.getId(), DataConstants.SERVER_SCOPE, attributeKvEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
log.debug("[{}][{}] Closing session", this.tenantId, sessionId);
|
||||
|
||||
@ -27,17 +27,21 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.common.util.ThingsBoardThreadFactory;
|
||||
import org.thingsboard.server.common.data.EdgeUpgradeMessage;
|
||||
import org.thingsboard.server.common.data.UpdateMessage;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger;
|
||||
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
|
||||
import org.thingsboard.server.queue.util.AfterStartUp;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.edge.instructions.EdgeInstallInstructionsService;
|
||||
import org.thingsboard.server.service.edge.instructions.EdgeUpgradeInstructionsService;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@ -65,12 +69,20 @@ public class DefaultUpdateService implements UpdateService {
|
||||
@Autowired
|
||||
private NotificationRuleProcessor notificationRuleProcessor;
|
||||
|
||||
@Autowired(required = false)
|
||||
private EdgeInstallInstructionsService edgeInstallInstructionsService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private EdgeUpgradeInstructionsService edgeUpgradeInstructionsService;
|
||||
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, ThingsBoardThreadFactory.forName("tb-update-service"));
|
||||
|
||||
private ScheduledFuture<?> checkUpdatesFuture = null;
|
||||
private final RestTemplate restClient = new RestTemplate();
|
||||
|
||||
private UpdateMessage updateMessage;
|
||||
private EdgeUpgradeMessage edgeUpgradeMessage;
|
||||
private String edgeInstallVersion;
|
||||
|
||||
private String platform;
|
||||
private String version;
|
||||
@ -82,6 +94,7 @@ public class DefaultUpdateService implements UpdateService {
|
||||
updateMessage = new UpdateMessage(false, version, "", "",
|
||||
"https://thingsboard.io/docs/reference/releases",
|
||||
"https://thingsboard.io/docs/reference/releases");
|
||||
edgeUpgradeMessage = new EdgeUpgradeMessage(new HashMap<>());
|
||||
if (updatesEnabled) {
|
||||
try {
|
||||
platform = System.getProperty("platform", "unknown");
|
||||
@ -141,6 +154,16 @@ public class DefaultUpdateService implements UpdateService {
|
||||
.updateInfo(updateMessage)
|
||||
.build());
|
||||
}
|
||||
ObjectNode edgeRequest = JacksonUtil.newObjectNode().put(VERSION_PARAM, version);
|
||||
String edgeInstallVersion = restClient.postForObject(UPDATE_SERVER_BASE_URL + "/api/v1/edge/installMapping", new HttpEntity<>(edgeRequest.toString(), headers), String.class);
|
||||
if (edgeInstallVersion != null) {
|
||||
edgeInstallInstructionsService.setAppVersion(edgeInstallVersion);
|
||||
edgeUpgradeInstructionsService.setAppVersion(edgeInstallVersion);
|
||||
}
|
||||
EdgeUpgradeMessage edgeUpgradeMessage = restClient.postForObject(UPDATE_SERVER_BASE_URL + "/api/v1/edge/upgradeMapping", new HttpEntity<>(edgeRequest.toString(), headers), EdgeUpgradeMessage.class);
|
||||
if (edgeUpgradeMessage != null) {
|
||||
edgeUpgradeInstructionsService.updateInstructionMap(edgeUpgradeMessage.getEdgeVersions());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.trace(e.getMessage());
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.TenantProfile;
|
||||
import org.thingsboard.server.common.data.EdgeUpgradeInfo;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.asset.AssetProfile;
|
||||
@ -74,6 +75,7 @@ import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
|
||||
import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.SyncCompletedMsg;
|
||||
@ -82,9 +84,11 @@ import org.thingsboard.server.gen.edge.v1.TenantUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
|
||||
import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.v1.UserUpdateMsg;
|
||||
import org.thingsboard.server.service.edge.instructions.EdgeUpgradeInstructionsService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -115,6 +119,9 @@ public class EdgeControllerTest extends AbstractControllerTest {
|
||||
@Autowired
|
||||
private EdgeDao edgeDao;
|
||||
|
||||
@Autowired
|
||||
private EdgeUpgradeInstructionsService edgeUpgradeInstructionsService;
|
||||
|
||||
static class Config {
|
||||
@Bean
|
||||
@Primary
|
||||
@ -1172,8 +1179,25 @@ public class EdgeControllerTest extends AbstractControllerTest {
|
||||
public void testGetEdgeInstallInstructions() throws Exception {
|
||||
Edge edge = constructEdge(tenantId, "Edge for Test Docker Install Instructions", "default", "7390c3a6-69b0-9910-d155-b90aca4b772e", "l7q4zsjplzwhk16geqxy");
|
||||
Edge savedEdge = doPost("/api/edge", edge, Edge.class);
|
||||
String installInstructions = doGet("/api/edge/instructions/" + savedEdge.getId().getId().toString() + "/docker", String.class);
|
||||
String installInstructions = doGet("/api/edge/instructions/install/" + savedEdge.getId().getId().toString() + "/docker", String.class);
|
||||
Assert.assertTrue(installInstructions.contains("l7q4zsjplzwhk16geqxy"));
|
||||
Assert.assertTrue(installInstructions.contains("7390c3a6-69b0-9910-d155-b90aca4b772e"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEdgeUpgradeInstructions() throws Exception {
|
||||
// UpdateInfo config is updating from Thingsboard Update server
|
||||
HashMap<String, EdgeUpgradeInfo> upgradeInfoHashMap = new HashMap<>();
|
||||
upgradeInfoHashMap.put("3.6.0", new EdgeUpgradeInfo(true, "3.6.1"));
|
||||
upgradeInfoHashMap.put("3.6.1", new EdgeUpgradeInfo(true, "3.6.2"));
|
||||
upgradeInfoHashMap.put("3.6.2", new EdgeUpgradeInfo(true, null));
|
||||
edgeUpgradeInstructionsService.updateInstructionMap(upgradeInfoHashMap);
|
||||
Edge edge = constructEdge("Edge for Test Docker Upgrade Instructions", "default");
|
||||
Edge savedEdge = doPost("/api/edge", edge, Edge.class);
|
||||
String body = "{\"edgeVersion\": \"V_3_6_0\"}";
|
||||
doPostAsync("/api/plugins/telemetry/EDGE/" + savedEdge.getId().getId() + "/attributes/SERVER_SCOPE", body, String.class, status().isOk());
|
||||
String upgradeInstructions = doGet("/api/edge/instructions/upgrade/" + EdgeVersion.V_3_6_0.name() + "/docker", String.class);
|
||||
Assert.assertTrue(upgradeInstructions.contains("Upgrading to 3.6.1EDGE"));
|
||||
Assert.assertTrue(upgradeInstructions.contains("Upgrading to 3.6.2EDGE"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,4 +52,4 @@ public class MqttV5ClientSparkplugBAttributesInProfileTest extends AbstractMqttV
|
||||
processClientDeviceWithCorrectAccessTokenPublish_AttributesInProfileContainsKeyAttributes();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,4 +78,4 @@ public class MqttV5ClientSparkplugBAttributesTest extends AbstractMqttV5ClientSp
|
||||
processClientDeviceWithCorrectAccessTokenPublishWithBirth_SharedAttributes_LongType_IfMetricFailedTypeCheck_SendValueOk();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.common.data;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class EdgeUpgradeInfo {
|
||||
private boolean requiresUpdateDb;
|
||||
private String nextEdgeVersion;
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.common.data;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@ApiModel
|
||||
public class EdgeUpgradeMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2872965507642822989L;
|
||||
|
||||
@ApiModelProperty(position = 1, value = "Mapping for upgrade versions and upgrade strategy (next ver).")
|
||||
private final Map<String, EdgeUpgradeInfo> edgeVersions;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -217,7 +217,7 @@ public class DeviceConnectivityUtil {
|
||||
return host;
|
||||
}
|
||||
|
||||
private static boolean isLocalhost(String host) {
|
||||
public static boolean isLocalhost(String host) {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(host);
|
||||
return inetAddress.isLoopbackAddress();
|
||||
|
||||
@ -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;
|
||||
@ -3261,12 +3261,18 @@ 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> getEdgeInstallInstructions(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());
|
||||
}
|
||||
|
||||
public Optional<EdgeInstructions> getEdgeUpgradeInstructions(String edgeVersion, String method) {
|
||||
ResponseEntity<EdgeInstructions> edgeUpgradeInstructionsResult =
|
||||
restTemplate.getForEntity(baseURL + "/api/edge/instructions/upgrade/{edgeVersion}/{method}", EdgeInstructions.class, edgeVersion, method);
|
||||
return Optional.ofNullable(edgeUpgradeInstructionsResult.getBody());
|
||||
}
|
||||
|
||||
public UUID saveEntitiesVersion(VersionCreateRequest request) {
|
||||
return restTemplate.postForEntity(baseURL + "/api/entities/vc/version", request, UUID.class).getBody();
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { PageLink, TimePageLink } from '@shared/models/page/page-link';
|
||||
import { PageData } from '@shared/models/page/page-data';
|
||||
import { EntitySubtype } from '@app/shared/models/entity-type.models';
|
||||
import { Edge, EdgeEvent, EdgeInfo, EdgeInstallInstructions, EdgeSearchQuery } from '@shared/models/edge.models';
|
||||
import { Edge, EdgeEvent, EdgeInfo, EdgeInstructions, EdgeSearchQuery } from '@shared/models/edge.models';
|
||||
import { EntityId } from '@shared/models/id/entity-id';
|
||||
import { BulkImportRequest, BulkImportResult } from '@shared/import-export/import-export.models';
|
||||
|
||||
@ -114,7 +114,11 @@ export class EdgeService {
|
||||
return this.http.post<BulkImportResult>('/api/edge/bulk_import', entitiesData, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
public getEdgeInstallInstructions(edgeId: string, method: string = 'ubuntu', config?: RequestConfig): Observable<EdgeInstallInstructions> {
|
||||
return this.http.get<EdgeInstallInstructions>(`/api/edge/instructions/${edgeId}/${method}`, defaultHttpOptionsFromConfig(config));
|
||||
public getEdgeInstallInstructions(edgeId: string, method: string = 'ubuntu', config?: RequestConfig): Observable<EdgeInstructions> {
|
||||
return this.http.get<EdgeInstructions>(`/api/edge/instructions/install/${edgeId}/${method}`, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
public getEdgeUpgradeInstructions(edgeVersion: string, method: string = 'ubuntu', config?: RequestConfig): Observable<EdgeInstructions> {
|
||||
return this.http.get<EdgeInstructions>(`/api/edge/instructions/upgrade/${edgeVersion}/${method}`, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,12 +21,21 @@ import { AppState } from '@core/core.state';
|
||||
import { Router } from '@angular/router';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ActionPreferencesPutUserSettings } from '@core/auth/auth.actions';
|
||||
import { EdgeInfo, EdgeInstructionsMethod } from '@shared/models/edge.models';
|
||||
import {
|
||||
EdgeInfo,
|
||||
EdgeInstructions,
|
||||
EdgeInstructionsMethod,
|
||||
edgeVersionAttributeKey
|
||||
} from '@shared/models/edge.models';
|
||||
import { EdgeService } from '@core/http/edge.service';
|
||||
import { AttributeService } from '@core/http/attribute.service';
|
||||
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
||||
import { mergeMap, Observable } from 'rxjs';
|
||||
|
||||
export interface EdgeInstructionsDialogData {
|
||||
edge: EdgeInfo;
|
||||
afterAdd: boolean;
|
||||
upgradeAvailable: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@ -49,12 +58,16 @@ export class EdgeInstructionsDialogComponent extends DialogComponent<EdgeInstruc
|
||||
protected router: Router,
|
||||
@Inject(MAT_DIALOG_DATA) private data: EdgeInstructionsDialogData,
|
||||
public dialogRef: MatDialogRef<EdgeInstructionsDialogComponent>,
|
||||
private attributeService: AttributeService,
|
||||
private edgeService: EdgeService) {
|
||||
super(store, router, dialogRef);
|
||||
|
||||
if (this.data.afterAdd) {
|
||||
this.dialogTitle = 'edge.install-connect-instructions-edge-created';
|
||||
this.showDontShowAgain = true;
|
||||
} else if (this.data.upgradeAvailable) {
|
||||
this.dialogTitle = 'edge.upgrade-instructions';
|
||||
this.showDontShowAgain = false;
|
||||
} else {
|
||||
this.dialogTitle = 'edge.install-connect-instructions';
|
||||
this.showDontShowAgain = false;
|
||||
@ -85,12 +98,22 @@ export class EdgeInstructionsDialogComponent extends DialogComponent<EdgeInstruc
|
||||
getInstructions(method: string) {
|
||||
if (!this.contentData[method]) {
|
||||
this.loadedInstructions = false;
|
||||
this.edgeService.getEdgeInstallInstructions(this.data.edge.id.id, method).subscribe(
|
||||
res => {
|
||||
this.contentData[method] = res.installInstructions;
|
||||
this.loadedInstructions = true;
|
||||
}
|
||||
);
|
||||
let edgeInstructions$: Observable<EdgeInstructions>;
|
||||
if (this.data.upgradeAvailable) {
|
||||
edgeInstructions$ = this.attributeService.getEntityAttributes(this.data.edge.id, AttributeScope.SERVER_SCOPE, [edgeVersionAttributeKey])
|
||||
.pipe(mergeMap(attributes => {
|
||||
if (attributes.length) {
|
||||
const edgeVersion = attributes[0].value;
|
||||
return this.edgeService.getEdgeUpgradeInstructions(edgeVersion, method);
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
edgeInstructions$ = this.edgeService.getEdgeInstallInstructions(this.data.edge.id.id, method);
|
||||
}
|
||||
edgeInstructions$.subscribe(res => {
|
||||
this.contentData[method] = res.instructions;
|
||||
this.loadedInstructions = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,13 +114,26 @@
|
||||
</button>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<button mat-raised-button color="primary"
|
||||
[disabled]="(isLoading$ | async)"
|
||||
(click)="onEntityAction($event, 'openInstructions')"
|
||||
[fxShow]="!isEdit && edgeScope !== 'customer_user'">
|
||||
<mat-icon>info_outline</mat-icon>
|
||||
<span>{{ 'edge.install-connect-instructions' | translate }}</span>
|
||||
</button>
|
||||
<div [ngSwitch]="upgradeAvailable">
|
||||
<ng-container *ngSwitchCase="false">
|
||||
<button mat-raised-button color="primary"
|
||||
[disabled]="(isLoading$ | async)"
|
||||
(click)="onEntityAction($event, 'openInstallInstructions')"
|
||||
[fxShow]="!isEdit && edgeScope !== 'customer_user'">
|
||||
<mat-icon>info_outline</mat-icon>
|
||||
<span>{{ 'edge.install-connect-instructions' | translate }}</span>
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="true">
|
||||
<button mat-raised-button color="primary"
|
||||
[disabled]="(isLoading$ | async)"
|
||||
(click)="onEntityAction($event, 'openUpgradeInstructions')"
|
||||
[fxShow]="!isEdit && edgeScope !== 'customer_user'">
|
||||
<mat-icon>info_outline</mat-icon>
|
||||
<span>{{ 'edge.upgrade-instructions' | translate }}</span>
|
||||
</button>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mat-padding" fxLayout="column">
|
||||
|
||||
@ -20,12 +20,15 @@ import { AppState } from '@core/core.state';
|
||||
import { EntityComponent } from '@home/components/entity/entity.component';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { EntityType } from '@shared/models/entity-type.models';
|
||||
import { EdgeInfo } from '@shared/models/edge.models';
|
||||
import { EdgeInfo, edgeVersionAttributeKey } from '@shared/models/edge.models';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
||||
import { ActionNotificationShow } from '@core/notification/notification.actions';
|
||||
import { generateSecret, guid } from '@core/utils';
|
||||
import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
|
||||
import { environment as env } from '@env/environment';
|
||||
import { AttributeService } from '@core/http/attribute.service';
|
||||
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-edge',
|
||||
@ -37,9 +40,11 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
|
||||
entityType = EntityType;
|
||||
|
||||
edgeScope: 'tenant' | 'customer' | 'customer_user';
|
||||
upgradeAvailable: boolean = false;
|
||||
|
||||
constructor(protected store: Store<AppState>,
|
||||
protected translate: TranslateService,
|
||||
private attributeService: AttributeService,
|
||||
@Inject('entity') protected entityValue: EdgeInfo,
|
||||
@Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<EdgeInfo>,
|
||||
public fb: UntypedFormBuilder,
|
||||
@ -95,6 +100,7 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
|
||||
}
|
||||
});
|
||||
this.generateRoutingKeyAndSecret(entity, this.entityForm);
|
||||
this.checkEdgeVersion();
|
||||
}
|
||||
|
||||
updateFormState() {
|
||||
@ -133,4 +139,25 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
|
||||
form.get('secret').patchValue(generateSecret(20), {emitEvent: false});
|
||||
}
|
||||
}
|
||||
|
||||
checkEdgeVersion() {
|
||||
this.attributeService.getEntityAttributes(this.entity.id, AttributeScope.SERVER_SCOPE, [edgeVersionAttributeKey])
|
||||
.subscribe(attributes => {
|
||||
if (attributes?.length) {
|
||||
const edgeVersion = attributes[0].value;
|
||||
const tbVersion = 'V_' + env.tbVersion.replaceAll('.', '_');
|
||||
this.upgradeAvailable = this.versionUpgradeSupported(edgeVersion) && (edgeVersion !== tbVersion);
|
||||
} else {
|
||||
this.upgradeAvailable = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private versionUpgradeSupported(edgeVersion: string): boolean {
|
||||
const edgeVersionArray = edgeVersion.split('_');
|
||||
const major = parseInt(edgeVersionArray[1]);
|
||||
const minor = parseInt(edgeVersionArray[2]);
|
||||
return major >= 3 && minor >= 6;
|
||||
}
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
|
||||
);
|
||||
}
|
||||
|
||||
openInstructions($event, edge: EdgeInfo, afterAdd = false) {
|
||||
openInstructions($event: Event, edge: EdgeInfo, afterAdd = false, upgradeAvailable = false) {
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
@ -568,7 +568,8 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
|
||||
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
||||
data: {
|
||||
edge,
|
||||
afterAdd
|
||||
afterAdd,
|
||||
upgradeAvailable
|
||||
}
|
||||
}).afterClosed().subscribe(() => {
|
||||
if (afterAdd) {
|
||||
@ -610,9 +611,12 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
|
||||
case 'syncEdge':
|
||||
this.syncEdge(action.event, action.entity);
|
||||
return true;
|
||||
case 'openInstructions':
|
||||
case 'openInstallInstructions':
|
||||
this.openInstructions(action.event, action.entity);
|
||||
return true;
|
||||
case 'openUpgradeInstructions':
|
||||
this.openInstructions(action.event, action.entity, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -179,8 +179,8 @@ export interface EdgeEvent extends BaseData<EventId> {
|
||||
body: string;
|
||||
}
|
||||
|
||||
export interface EdgeInstallInstructions {
|
||||
installInstructions: string;
|
||||
export interface EdgeInstructions {
|
||||
instructions: string;
|
||||
}
|
||||
|
||||
export enum EdgeInstructionsMethod {
|
||||
@ -188,3 +188,5 @@ export enum EdgeInstructionsMethod {
|
||||
centos,
|
||||
docker
|
||||
}
|
||||
|
||||
export const edgeVersionAttributeKey = 'edgeVersion';
|
||||
|
||||
@ -2021,6 +2021,7 @@
|
||||
"sync-process-started-successfully": "Sync process started successfully!",
|
||||
"missing-related-rule-chains-title": "Edge has missing related rule chain(s)",
|
||||
"missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge. <br><br> List of missing rule chain(s): <br> {{missingRuleChains}}",
|
||||
"upgrade-instructions": "Upgrade Instructions",
|
||||
"widget-datasource-error": "This widget supports only EDGE entity datasource"
|
||||
},
|
||||
"edge-event": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user