Showing
32 changed files
with
1421 additions
and
2 deletions
@@ -29,7 +29,7 @@ services: | @@ -29,7 +29,7 @@ services: | ||
29 | environment: | 29 | environment: |
30 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 | 30 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 |
31 | KAFKA_LISTENERS: INSIDE://:9093,OUTSIDE://:9092 | 31 | KAFKA_LISTENERS: INSIDE://:9093,OUTSIDE://:9092 |
32 | - KAFKA_ADVERTISED_LISTENERS: INSIDE://:9093,OUTSIDE://${KAFKA_HOSTNAME}:9092 | 32 | + KAFKA_ADVERTISED_LISTENERS: INSIDE://:9093,OUTSIDE://${EXTERNAL_HOSTNAME}:9092 |
33 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT | 33 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT |
34 | KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE | 34 | KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE |
35 | KAFKA_CREATE_TOPICS: "${KAFKA_TOPICS}" | 35 | KAFKA_CREATE_TOPICS: "${KAFKA_TOPICS}" |
@@ -44,3 +44,14 @@ services: | @@ -44,3 +44,14 @@ services: | ||
44 | - tb-js-executor.env | 44 | - tb-js-executor.env |
45 | depends_on: | 45 | depends_on: |
46 | - kafka | 46 | - kafka |
47 | + tb-web-ui: | ||
48 | + image: "local-maven-build/tb-web-ui:latest" | ||
49 | + ports: | ||
50 | + - "8090:8090" | ||
51 | + environment: | ||
52 | + HTTP_BIND_ADDRESS: 0.0.0.0 | ||
53 | + HTTP_BIND_PORT: 8090 | ||
54 | + TB_HOST: ${EXTERNAL_HOSTNAME} | ||
55 | + TB_PORT: 8080 | ||
56 | + env_file: | ||
57 | + - tb-web-ui.env |
msa/docker/tb-web-ui.env
0 → 100644
msa/web-ui/.gitignore
0 → 100644
1 | +*.toDelete | ||
2 | +output/** | ||
3 | +*.class | ||
4 | +*~ | ||
5 | +*.iml | ||
6 | +*/.idea/** | ||
7 | +.idea/** | ||
8 | +.idea | ||
9 | +*.log | ||
10 | +*.log.[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] | ||
11 | +*/.classpath | ||
12 | +.classpath | ||
13 | +*/.project | ||
14 | +.project | ||
15 | +.cache/** | ||
16 | +target/ | ||
17 | +logs/ | ||
18 | +build/ | ||
19 | +.settings/ | ||
20 | +/bin | ||
21 | +bin/ | ||
22 | +**/dependency-reduced-pom.xml | ||
23 | +pom.xml.versionsBackup | ||
24 | +.DS_Store | ||
25 | +**/.gradle | ||
26 | +**/local.properties | ||
27 | +**/build | ||
28 | +**/target | ||
29 | +**/.env | ||
30 | +node_modules | ||
31 | +package-lock.json |
msa/web-ui/build.gradle
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +import org.apache.tools.ant.filters.ReplaceTokens | ||
17 | + | ||
18 | +buildscript { | ||
19 | + ext { | ||
20 | + osPackageVersion = "3.8.0" | ||
21 | + } | ||
22 | + repositories { | ||
23 | + jcenter() | ||
24 | + } | ||
25 | + dependencies { | ||
26 | + classpath("com.netflix.nebula:gradle-ospackage-plugin:${osPackageVersion}") | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +apply plugin: "nebula.ospackage" | ||
31 | + | ||
32 | +buildDir = projectBuildDir | ||
33 | +version = projectVersion | ||
34 | +distsDirName = "./" | ||
35 | + | ||
36 | +// OS Package plugin configuration | ||
37 | +ospackage { | ||
38 | + packageName = pkgName | ||
39 | + version = "${project.version}" | ||
40 | + release = 1 | ||
41 | + os = LINUX | ||
42 | + type = BINARY | ||
43 | + | ||
44 | + into pkgInstallFolder | ||
45 | + | ||
46 | + user pkgUser | ||
47 | + permissionGroup pkgUser | ||
48 | + | ||
49 | + // Copy the executable file | ||
50 | + from("target/package/linux/bin/${pkgName}") { | ||
51 | + fileMode 0500 | ||
52 | + into "bin" | ||
53 | + } | ||
54 | + | ||
55 | + // Copy the init file | ||
56 | + from("target/package/linux/init/${pkgName}") { | ||
57 | + fileMode 0500 | ||
58 | + into "init" | ||
59 | + } | ||
60 | + | ||
61 | + // Copy the config files | ||
62 | + from("target/package/linux/conf") { | ||
63 | + fileType CONFIG | NOREPLACE | ||
64 | + fileMode 0754 | ||
65 | + into "conf" | ||
66 | + } | ||
67 | + | ||
68 | + // Copy web files | ||
69 | + from("target/package/linux/web") { | ||
70 | + into "web" | ||
71 | + } | ||
72 | + | ||
73 | +} | ||
74 | + | ||
75 | +// Configure our RPM build task | ||
76 | +buildRpm { | ||
77 | + | ||
78 | + arch = X86_64 | ||
79 | + | ||
80 | + version = projectVersion.replace('-', '') | ||
81 | + archiveName = "${pkgName}.rpm" | ||
82 | + | ||
83 | + preInstall file("${buildDir}/control/rpm/preinst") | ||
84 | + postInstall file("${buildDir}/control/rpm/postinst") | ||
85 | + preUninstall file("${buildDir}/control/rpm/prerm") | ||
86 | + postUninstall file("${buildDir}/control/rpm/postrm") | ||
87 | + | ||
88 | + user pkgUser | ||
89 | + permissionGroup pkgUser | ||
90 | + | ||
91 | + // Copy the system unit files | ||
92 | + from("${buildDir}/control/${pkgName}.service") { | ||
93 | + addParentDirs = false | ||
94 | + fileMode 0644 | ||
95 | + into "/usr/lib/systemd/system" | ||
96 | + } | ||
97 | + | ||
98 | + directory(pkgLogFolder, 0755) | ||
99 | + link("/etc/${pkgName}/conf", "${pkgInstallFolder}/conf") | ||
100 | +} | ||
101 | + | ||
102 | +// Same as the buildRpm task | ||
103 | +buildDeb { | ||
104 | + | ||
105 | + arch = "amd64" | ||
106 | + | ||
107 | + archiveName = "${pkgName}.deb" | ||
108 | + | ||
109 | + configurationFile("${pkgInstallFolder}/conf/${pkgName}.conf") | ||
110 | + configurationFile("${pkgInstallFolder}/conf/custom-environment-variables.yml") | ||
111 | + configurationFile("${pkgInstallFolder}/conf/default.yml") | ||
112 | + configurationFile("${pkgInstallFolder}/conf/logger.js") | ||
113 | + | ||
114 | + preInstall file("${buildDir}/control/deb/preinst") | ||
115 | + postInstall file("${buildDir}/control/deb/postinst") | ||
116 | + preUninstall file("${buildDir}/control/deb/prerm") | ||
117 | + postUninstall file("${buildDir}/control/deb/postrm") | ||
118 | + | ||
119 | + user pkgUser | ||
120 | + permissionGroup pkgUser | ||
121 | + | ||
122 | + directory(pkgLogFolder, 0755) | ||
123 | + link("/etc/init.d/${pkgName}", "${pkgInstallFolder}/init/${pkgName}") | ||
124 | + link("/etc/${pkgName}/conf", "${pkgInstallFolder}/conf") | ||
125 | +} |
1 | +# | ||
2 | +# Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +# | ||
4 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +# you may not use this file except in compliance with the License. | ||
6 | +# You may obtain a copy of the License at | ||
7 | +# | ||
8 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +# | ||
10 | +# Unless required by applicable law or agreed to in writing, software | ||
11 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +# See the License for the specific language governing permissions and | ||
14 | +# limitations under the License. | ||
15 | +# | ||
16 | + | ||
17 | +server: | ||
18 | + # Server bind address | ||
19 | + address: "HTTP_BIND_ADDRESS" | ||
20 | + # Server bind port | ||
21 | + port: "HTTP_BIND_PORT" | ||
22 | +thingsboard: | ||
23 | + # ThingsBoard node host | ||
24 | + host: "TB_HOST" | ||
25 | + # ThingsBoard node port | ||
26 | + port: "TB_PORT" | ||
27 | +logger: | ||
28 | + level: "LOGGER_LEVEL" | ||
29 | + path: "LOG_FOLDER" | ||
30 | + filename: "LOGGER_FILENAME" |
msa/web-ui/config/default.yml
0 → 100644
1 | +# | ||
2 | +# Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +# | ||
4 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +# you may not use this file except in compliance with the License. | ||
6 | +# You may obtain a copy of the License at | ||
7 | +# | ||
8 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +# | ||
10 | +# Unless required by applicable law or agreed to in writing, software | ||
11 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +# See the License for the specific language governing permissions and | ||
14 | +# limitations under the License. | ||
15 | +# | ||
16 | + | ||
17 | +server: | ||
18 | + # Server bind address | ||
19 | + address: "0.0.0.0" | ||
20 | + # Server bind port | ||
21 | + port: "8090" | ||
22 | +thingsboard: | ||
23 | + # ThingsBoard node host | ||
24 | + host: "localhost" | ||
25 | + # ThingsBoard node port | ||
26 | + port: "8080" | ||
27 | +logger: | ||
28 | + level: "info" | ||
29 | + path: "logs" | ||
30 | + filename: "tb-web-ui-%DATE%.log" |
msa/web-ui/config/logger.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +var config = require('config'), | ||
17 | + path = require('path'), | ||
18 | + DailyRotateFile = require('winston-daily-rotate-file'); | ||
19 | + | ||
20 | +const { createLogger, format, transports } = require('winston'); | ||
21 | +const { combine, timestamp, label, printf, splat } = format; | ||
22 | + | ||
23 | +var loggerTransports = []; | ||
24 | + | ||
25 | +if (process.env.NODE_ENV !== 'production' || process.env.DOCKER_MODE === 'true') { | ||
26 | + loggerTransports.push(new transports.Console({ | ||
27 | + handleExceptions: true | ||
28 | + })); | ||
29 | +} else { | ||
30 | + var filename = path.join(config.get('logger.path'), config.get('logger.filename')); | ||
31 | + var transport = new (DailyRotateFile)({ | ||
32 | + filename: filename, | ||
33 | + datePattern: 'YYYY-MM-DD-HH', | ||
34 | + zippedArchive: true, | ||
35 | + maxSize: '20m', | ||
36 | + maxFiles: '14d', | ||
37 | + handleExceptions: true | ||
38 | + }); | ||
39 | + loggerTransports.push(transport); | ||
40 | +} | ||
41 | + | ||
42 | +const tbFormat = printf(info => { | ||
43 | + return `${info.timestamp} [${info.label}] ${info.level.toUpperCase()}: ${info.message}`; | ||
44 | +}); | ||
45 | + | ||
46 | +function _logger(moduleLabel) { | ||
47 | + return createLogger({ | ||
48 | + level: config.get('logger.level'), | ||
49 | + format:combine( | ||
50 | + splat(), | ||
51 | + label({ label: moduleLabel }), | ||
52 | + timestamp({format: 'YYYY-MM-DD HH:mm:ss,SSS'}), | ||
53 | + tbFormat | ||
54 | + ), | ||
55 | + transports: loggerTransports | ||
56 | + }); | ||
57 | +} | ||
58 | + | ||
59 | +module.exports = _logger; |
msa/web-ui/config/tb-web-ui.conf
0 → 100644
1 | +# | ||
2 | +# Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +# | ||
4 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +# you may not use this file except in compliance with the License. | ||
6 | +# You may obtain a copy of the License at | ||
7 | +# | ||
8 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +# | ||
10 | +# Unless required by applicable law or agreed to in writing, software | ||
11 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +# See the License for the specific language governing permissions and | ||
14 | +# limitations under the License. | ||
15 | +# | ||
16 | + | ||
17 | +export NODE_CONFIG_DIR=${pkg.installFolder}/conf | ||
18 | +export LOG_FOLDER=${pkg.logFolder} | ||
19 | +export NODE_ENV=production | ||
20 | +export WEB_FOLDER=${pkg.installFolder}/web |
msa/web-ui/docker/Dockerfile
0 → 100644
1 | +# | ||
2 | +# Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +# | ||
4 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +# you may not use this file except in compliance with the License. | ||
6 | +# You may obtain a copy of the License at | ||
7 | +# | ||
8 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +# | ||
10 | +# Unless required by applicable law or agreed to in writing, software | ||
11 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +# See the License for the specific language governing permissions and | ||
14 | +# limitations under the License. | ||
15 | +# | ||
16 | + | ||
17 | +FROM debian:stretch | ||
18 | + | ||
19 | +COPY start-web-ui.sh ${pkg.name}.deb /tmp/ | ||
20 | + | ||
21 | +RUN chmod a+x /tmp/*.sh \ | ||
22 | + && mv /tmp/start-web-ui.sh /usr/bin | ||
23 | + | ||
24 | +RUN dpkg -i /tmp/${pkg.name}.deb | ||
25 | + | ||
26 | +CMD ["start-web-ui.sh"] |
msa/web-ui/docker/start-web-ui.sh
0 → 100755
1 | +#!/bin/bash | ||
2 | +# | ||
3 | +# Copyright © 2016-2018 The Thingsboard Authors | ||
4 | +# | ||
5 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | +# you may not use this file except in compliance with the License. | ||
7 | +# You may obtain a copy of the License at | ||
8 | +# | ||
9 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | +# | ||
11 | +# Unless required by applicable law or agreed to in writing, software | ||
12 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | +# See the License for the specific language governing permissions and | ||
15 | +# limitations under the License. | ||
16 | +# | ||
17 | + | ||
18 | + | ||
19 | +echo "Starting '${project.name}' ..." | ||
20 | + | ||
21 | +CONF_FOLDER="${pkg.installFolder}/conf" | ||
22 | + | ||
23 | +mainfile=${pkg.installFolder}/bin/${pkg.name} | ||
24 | +configfile=${pkg.name}.conf | ||
25 | +identity=${pkg.name} | ||
26 | + | ||
27 | +source "${CONF_FOLDER}/${configfile}" | ||
28 | + | ||
29 | +su -s /bin/sh -c "$mainfile" |
msa/web-ui/install.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +const fs = require('fs'); | ||
17 | +const fse = require('fs-extra'); | ||
18 | +const path = require('path'); | ||
19 | + | ||
20 | +let _projectRoot = null; | ||
21 | + | ||
22 | + | ||
23 | +(async() => { | ||
24 | + await fse.move(path.join(projectRoot(), 'target', 'thingsboard-web-ui-linux'), | ||
25 | + path.join(targetPackageDir('linux'), 'bin', 'tb-web-ui'), | ||
26 | + {overwrite: true}); | ||
27 | + await fse.move(path.join(projectRoot(), 'target', 'thingsboard-web-ui-win.exe'), | ||
28 | + path.join(targetPackageDir('windows'), 'bin', 'tb-web-ui.exe'), | ||
29 | + {overwrite: true}); | ||
30 | +})(); | ||
31 | + | ||
32 | + | ||
33 | +function projectRoot() { | ||
34 | + if (!_projectRoot) { | ||
35 | + _projectRoot = __dirname; | ||
36 | + } | ||
37 | + return _projectRoot; | ||
38 | +} | ||
39 | + | ||
40 | +function targetPackageDir(platform) { | ||
41 | + return path.join(projectRoot(), 'target', 'package', platform); | ||
42 | +} |
msa/web-ui/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "thingsboard-web-ui", | ||
3 | + "private": true, | ||
4 | + "version": "2.2.0", | ||
5 | + "description": "ThingsBoard Web UI Microservice", | ||
6 | + "main": "server.js", | ||
7 | + "bin": "server.js", | ||
8 | + "scripts": { | ||
9 | + "install": "pkg -t node8-linux-x64,node8-win-x64 --out-path ./target . && node install.js", | ||
10 | + "test": "echo \"Error: no test specified\" && exit 1", | ||
11 | + "start": "WEB_FOLDER=./target/web nodemon server.js", | ||
12 | + "start-prod": "NODE_ENV=production nodemon server.js" | ||
13 | + }, | ||
14 | + "dependencies": { | ||
15 | + "config": "^1.30.0", | ||
16 | + "connect-history-api-fallback": "^1.5.0", | ||
17 | + "express": "^4.16.3", | ||
18 | + "http": "0.0.0", | ||
19 | + "http-proxy": "^1.17.0", | ||
20 | + "js-yaml": "^3.12.0", | ||
21 | + "winston": "^3.0.0", | ||
22 | + "winston-daily-rotate-file": "^3.2.1" | ||
23 | + }, | ||
24 | + "engine": "node >= 5.9.0", | ||
25 | + "nyc": { | ||
26 | + "exclude": [ | ||
27 | + "test", | ||
28 | + "__tests__", | ||
29 | + "node_modules", | ||
30 | + "target" | ||
31 | + ] | ||
32 | + }, | ||
33 | + "devDependencies": { | ||
34 | + "fs-extra": "^6.0.1", | ||
35 | + "nodemon": "^1.17.5", | ||
36 | + "pkg": "^4.3.3" | ||
37 | + } | ||
38 | +} |
msa/web-ui/pom.xml
0 → 100644
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2018 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
20 | + <modelVersion>4.0.0</modelVersion> | ||
21 | + <parent> | ||
22 | + <groupId>org.thingsboard</groupId> | ||
23 | + <version>2.2.0-SNAPSHOT</version> | ||
24 | + <artifactId>msa</artifactId> | ||
25 | + </parent> | ||
26 | + <groupId>org.thingsboard.msa</groupId> | ||
27 | + <artifactId>web-ui</artifactId> | ||
28 | + <packaging>pom</packaging> | ||
29 | + | ||
30 | + <name>ThingsBoard Web UI Microservice</name> | ||
31 | + <url>https://thingsboard.io</url> | ||
32 | + <description>Service for hosting ThingsBoard Web UI</description> | ||
33 | + | ||
34 | + <properties> | ||
35 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
36 | + <main.dir>${basedir}/../..</main.dir> | ||
37 | + <pkg.name>tb-web-ui</pkg.name> | ||
38 | + <pkg.user>thingsboard</pkg.user> | ||
39 | + <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder> | ||
40 | + <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> | ||
41 | + <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist> | ||
42 | + <pkg.win.dist>${project.build.directory}/package/windows</pkg.win.dist> | ||
43 | + <dockerfile.skip>true</dockerfile.skip> | ||
44 | + </properties> | ||
45 | + | ||
46 | + <dependencies> | ||
47 | + <dependency> | ||
48 | + <groupId>org.thingsboard</groupId> | ||
49 | + <artifactId>ui</artifactId> | ||
50 | + <version>${project.version}</version> | ||
51 | + <type>jar</type> | ||
52 | + <scope>provided</scope> | ||
53 | + </dependency> | ||
54 | + <dependency> | ||
55 | + <groupId>com.sun.winsw</groupId> | ||
56 | + <artifactId>winsw</artifactId> | ||
57 | + <classifier>bin</classifier> | ||
58 | + <type>exe</type> | ||
59 | + <scope>provided</scope> | ||
60 | + </dependency> | ||
61 | + </dependencies> | ||
62 | + | ||
63 | + <build> | ||
64 | + <plugins> | ||
65 | + <plugin> | ||
66 | + <groupId>com.github.eirslett</groupId> | ||
67 | + <artifactId>frontend-maven-plugin</artifactId> | ||
68 | + <version>1.0</version> | ||
69 | + <configuration> | ||
70 | + <installDirectory>target</installDirectory> | ||
71 | + <workingDirectory>${basedir}</workingDirectory> | ||
72 | + </configuration> | ||
73 | + <executions> | ||
74 | + <execution> | ||
75 | + <id>install node and npm</id> | ||
76 | + <goals> | ||
77 | + <goal>install-node-and-npm</goal> | ||
78 | + </goals> | ||
79 | + <configuration> | ||
80 | + <nodeVersion>v8.11.3</nodeVersion> | ||
81 | + <npmVersion>5.6.0</npmVersion> | ||
82 | + </configuration> | ||
83 | + </execution> | ||
84 | + <execution> | ||
85 | + <id>npm install</id> | ||
86 | + <goals> | ||
87 | + <goal>npm</goal> | ||
88 | + </goals> | ||
89 | + <configuration> | ||
90 | + <arguments>install</arguments> | ||
91 | + </configuration> | ||
92 | + </execution> | ||
93 | + </executions> | ||
94 | + </plugin> | ||
95 | + <plugin> | ||
96 | + <groupId>org.apache.maven.plugins</groupId> | ||
97 | + <artifactId>maven-dependency-plugin</artifactId> | ||
98 | + <executions> | ||
99 | + <execution> | ||
100 | + <id>extract-web-ui</id> | ||
101 | + <goals> | ||
102 | + <goal>unpack</goal> | ||
103 | + </goals> | ||
104 | + <configuration> | ||
105 | + <artifactItems> | ||
106 | + <artifactItem> | ||
107 | + <groupId>org.thingsboard</groupId> | ||
108 | + <artifactId>ui</artifactId> | ||
109 | + <type>jar</type> | ||
110 | + <overWrite>false</overWrite> | ||
111 | + <outputDirectory>${project.build.directory}/web</outputDirectory> | ||
112 | + </artifactItem> | ||
113 | + </artifactItems> | ||
114 | + </configuration> | ||
115 | + </execution> | ||
116 | + <execution> | ||
117 | + <id>copy-winsw-service</id> | ||
118 | + <phase>package</phase> | ||
119 | + <goals> | ||
120 | + <goal>copy</goal> | ||
121 | + </goals> | ||
122 | + <configuration> | ||
123 | + <artifactItems> | ||
124 | + <artifactItem> | ||
125 | + <groupId>com.sun.winsw</groupId> | ||
126 | + <artifactId>winsw</artifactId> | ||
127 | + <classifier>bin</classifier> | ||
128 | + <type>exe</type> | ||
129 | + <destFileName>service.exe</destFileName> | ||
130 | + </artifactItem> | ||
131 | + </artifactItems> | ||
132 | + <outputDirectory>${pkg.win.dist}</outputDirectory> | ||
133 | + </configuration> | ||
134 | + </execution> | ||
135 | + </executions> | ||
136 | + </plugin> | ||
137 | + <plugin> | ||
138 | + <groupId>org.apache.maven.plugins</groupId> | ||
139 | + <artifactId>maven-resources-plugin</artifactId> | ||
140 | + <executions> | ||
141 | + <execution> | ||
142 | + <id>copy-linux-conf</id> | ||
143 | + <phase>process-resources</phase> | ||
144 | + <goals> | ||
145 | + <goal>copy-resources</goal> | ||
146 | + </goals> | ||
147 | + <configuration> | ||
148 | + <outputDirectory>${pkg.linux.dist}/conf</outputDirectory> | ||
149 | + <resources> | ||
150 | + <resource> | ||
151 | + <directory>config</directory> | ||
152 | + <filtering>true</filtering> | ||
153 | + </resource> | ||
154 | + </resources> | ||
155 | + <filters> | ||
156 | + <filter>src/main/filters/unix.properties</filter> | ||
157 | + </filters> | ||
158 | + </configuration> | ||
159 | + </execution> | ||
160 | + <execution> | ||
161 | + <id>copy-linux-init</id> | ||
162 | + <phase>process-resources</phase> | ||
163 | + <goals> | ||
164 | + <goal>copy-resources</goal> | ||
165 | + </goals> | ||
166 | + <configuration> | ||
167 | + <outputDirectory>${pkg.linux.dist}/init</outputDirectory> | ||
168 | + <resources> | ||
169 | + <resource> | ||
170 | + <directory>src/main/scripts/init</directory> | ||
171 | + <filtering>true</filtering> | ||
172 | + </resource> | ||
173 | + </resources> | ||
174 | + <filters> | ||
175 | + <filter>src/main/filters/unix.properties</filter> | ||
176 | + </filters> | ||
177 | + </configuration> | ||
178 | + </execution> | ||
179 | + <execution> | ||
180 | + <id>copy-win-conf</id> | ||
181 | + <phase>process-resources</phase> | ||
182 | + <goals> | ||
183 | + <goal>copy-resources</goal> | ||
184 | + </goals> | ||
185 | + <configuration> | ||
186 | + <outputDirectory>${pkg.win.dist}/conf</outputDirectory> | ||
187 | + <resources> | ||
188 | + <resource> | ||
189 | + <directory>config</directory> | ||
190 | + <excludes> | ||
191 | + <exclude>tb-web-ui.conf</exclude> | ||
192 | + </excludes> | ||
193 | + <filtering>true</filtering> | ||
194 | + </resource> | ||
195 | + </resources> | ||
196 | + <filters> | ||
197 | + <filter>src/main/filters/windows.properties</filter> | ||
198 | + </filters> | ||
199 | + </configuration> | ||
200 | + </execution> | ||
201 | + <execution> | ||
202 | + <id>copy-control</id> | ||
203 | + <phase>process-resources</phase> | ||
204 | + <goals> | ||
205 | + <goal>copy-resources</goal> | ||
206 | + </goals> | ||
207 | + <configuration> | ||
208 | + <outputDirectory>${project.build.directory}/control</outputDirectory> | ||
209 | + <resources> | ||
210 | + <resource> | ||
211 | + <directory>src/main/scripts/control</directory> | ||
212 | + <filtering>true</filtering> | ||
213 | + </resource> | ||
214 | + </resources> | ||
215 | + <filters> | ||
216 | + <filter>src/main/filters/unix.properties</filter> | ||
217 | + </filters> | ||
218 | + </configuration> | ||
219 | + </execution> | ||
220 | + <execution> | ||
221 | + <id>copy-windows-control</id> | ||
222 | + <phase>process-resources</phase> | ||
223 | + <goals> | ||
224 | + <goal>copy-resources</goal> | ||
225 | + </goals> | ||
226 | + <configuration> | ||
227 | + <outputDirectory>${pkg.win.dist}</outputDirectory> | ||
228 | + <resources> | ||
229 | + <resource> | ||
230 | + <directory>src/main/scripts/windows</directory> | ||
231 | + <filtering>true</filtering> | ||
232 | + </resource> | ||
233 | + </resources> | ||
234 | + <filters> | ||
235 | + <filter>src/main/filters/windows.properties</filter> | ||
236 | + </filters> | ||
237 | + </configuration> | ||
238 | + </execution> | ||
239 | + <execution> | ||
240 | + <id>copy-docker-config</id> | ||
241 | + <phase>process-resources</phase> | ||
242 | + <goals> | ||
243 | + <goal>copy-resources</goal> | ||
244 | + </goals> | ||
245 | + <configuration> | ||
246 | + <outputDirectory>${project.build.directory}</outputDirectory> | ||
247 | + <resources> | ||
248 | + <resource> | ||
249 | + <directory>docker</directory> | ||
250 | + <filtering>true</filtering> | ||
251 | + </resource> | ||
252 | + </resources> | ||
253 | + </configuration> | ||
254 | + </execution> | ||
255 | + </executions> | ||
256 | + </plugin> | ||
257 | + <plugin> | ||
258 | + <groupId>org.fortasoft</groupId> | ||
259 | + <artifactId>gradle-maven-plugin</artifactId> | ||
260 | + <configuration> | ||
261 | + <tasks> | ||
262 | + <task>build</task> | ||
263 | + <task>buildDeb</task> | ||
264 | + <task>buildRpm</task> | ||
265 | + </tasks> | ||
266 | + <args> | ||
267 | + <arg>-PprojectBuildDir=${project.build.directory}</arg> | ||
268 | + <arg>-PprojectVersion=${project.version}</arg> | ||
269 | + <arg>-PpkgName=${pkg.name}</arg> | ||
270 | + <arg>-PpkgUser=${pkg.user}</arg> | ||
271 | + <arg>-PpkgInstallFolder=${pkg.installFolder}</arg> | ||
272 | + <arg>-PpkgLogFolder=${pkg.unixLogFolder}</arg> | ||
273 | + </args> | ||
274 | + </configuration> | ||
275 | + <executions> | ||
276 | + <execution> | ||
277 | + <phase>package</phase> | ||
278 | + <goals> | ||
279 | + <goal>invoke</goal> | ||
280 | + </goals> | ||
281 | + </execution> | ||
282 | + </executions> | ||
283 | + </plugin> | ||
284 | + <plugin> | ||
285 | + <groupId>org.apache.maven.plugins</groupId> | ||
286 | + <artifactId>maven-assembly-plugin</artifactId> | ||
287 | + <version>3.0.0</version> | ||
288 | + <configuration> | ||
289 | + <finalName>${pkg.name}</finalName> | ||
290 | + <descriptors> | ||
291 | + <descriptor>src/main/assembly/windows.xml</descriptor> | ||
292 | + </descriptors> | ||
293 | + </configuration> | ||
294 | + <executions> | ||
295 | + <execution> | ||
296 | + <id>assembly</id> | ||
297 | + <phase>package</phase> | ||
298 | + <goals> | ||
299 | + <goal>single</goal> | ||
300 | + </goals> | ||
301 | + </execution> | ||
302 | + </executions> | ||
303 | + </plugin> | ||
304 | + <plugin> | ||
305 | + <groupId>com.spotify</groupId> | ||
306 | + <artifactId>dockerfile-maven-plugin</artifactId> | ||
307 | + <version>1.4.4</version> | ||
308 | + <executions> | ||
309 | + <execution> | ||
310 | + <id>build-docker-image</id> | ||
311 | + <phase>pre-integration-test</phase> | ||
312 | + <goals> | ||
313 | + <goal>build</goal> | ||
314 | + </goals> | ||
315 | + </execution> | ||
316 | + </executions> | ||
317 | + <configuration> | ||
318 | + <skip>${dockerfile.skip}</skip> | ||
319 | + <repository>local-maven-build/${pkg.name}</repository> | ||
320 | + <verbose>true</verbose> | ||
321 | + <googleContainerRegistryEnabled>false</googleContainerRegistryEnabled> | ||
322 | + <contextDirectory>${project.build.directory}</contextDirectory> | ||
323 | + </configuration> | ||
324 | + </plugin> | ||
325 | + </plugins> | ||
326 | + </build> | ||
327 | + <profiles> | ||
328 | + <profile> | ||
329 | + <id>npm-start</id> | ||
330 | + <activation> | ||
331 | + <property> | ||
332 | + <name>npm-start</name> | ||
333 | + </property> | ||
334 | + </activation> | ||
335 | + <build> | ||
336 | + <plugins> | ||
337 | + <plugin> | ||
338 | + <groupId>com.github.eirslett</groupId> | ||
339 | + <artifactId>frontend-maven-plugin</artifactId> | ||
340 | + <version>1.0</version> | ||
341 | + <configuration> | ||
342 | + <installDirectory>target</installDirectory> | ||
343 | + <workingDirectory>${basedir}</workingDirectory> | ||
344 | + </configuration> | ||
345 | + <executions> | ||
346 | + <execution> | ||
347 | + <id>npm start</id> | ||
348 | + <goals> | ||
349 | + <goal>npm</goal> | ||
350 | + </goals> | ||
351 | + | ||
352 | + <configuration> | ||
353 | + <arguments>start</arguments> | ||
354 | + </configuration> | ||
355 | + </execution> | ||
356 | + </executions> | ||
357 | + </plugin> | ||
358 | + </plugins> | ||
359 | + </build> | ||
360 | + </profile> | ||
361 | + </profiles> | ||
362 | + <repositories> | ||
363 | + <repository> | ||
364 | + <id>jenkins</id> | ||
365 | + <name>Jenkins Repository</name> | ||
366 | + <url>http://repo.jenkins-ci.org/releases</url> | ||
367 | + <snapshots> | ||
368 | + <enabled>false</enabled> | ||
369 | + </snapshots> | ||
370 | + </repository> | ||
371 | + </repositories> | ||
372 | +</project> |
msa/web-ui/server.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +const config = require('config'), | ||
18 | + logger = require('./config/logger')('main'), | ||
19 | + express = require('express'), | ||
20 | + http = require('http'), | ||
21 | + httpProxy = require('http-proxy'), | ||
22 | + path = require('path'), | ||
23 | + historyApiFallback = require("connect-history-api-fallback"); | ||
24 | + | ||
25 | +var server; | ||
26 | + | ||
27 | +(async() => { | ||
28 | + try { | ||
29 | + logger.info('Starting ThingsBoard Web UI Microservice...'); | ||
30 | + | ||
31 | + const bindAddress = config.get('server.address'); | ||
32 | + const bindPort = config.get('server.port'); | ||
33 | + | ||
34 | + const thingsboardHost = config.get('thingsboard.host'); | ||
35 | + const thingsboardPort = config.get('thingsboard.port'); | ||
36 | + | ||
37 | + logger.info('Bind address: %s', bindAddress); | ||
38 | + logger.info('Bind port: %s', bindPort); | ||
39 | + logger.info('ThingsBoard host: %s', thingsboardHost); | ||
40 | + logger.info('ThingsBoard port: %s', thingsboardPort); | ||
41 | + | ||
42 | + var webDir = path.join(__dirname, 'web'); | ||
43 | + | ||
44 | + if (typeof process.env.WEB_FOLDER === 'string') { | ||
45 | + webDir = path.resolve(process.env.WEB_FOLDER); | ||
46 | + } | ||
47 | + logger.info('Web folder: %s', webDir); | ||
48 | + | ||
49 | + const app = express(); | ||
50 | + server = http.createServer(app); | ||
51 | + | ||
52 | + const apiProxy = httpProxy.createProxyServer({ | ||
53 | + target: { | ||
54 | + host: thingsboardHost, | ||
55 | + port: thingsboardPort | ||
56 | + } | ||
57 | + }); | ||
58 | + | ||
59 | + apiProxy.on('error', function (err, req, res) { | ||
60 | + logger.warn('API proxy error: %s', err.message); | ||
61 | + res.writeHead(500); | ||
62 | + if (err.code && err.code === 'ECONNREFUSED') { | ||
63 | + res.end('Unable to connect to ThingsBoard server.'); | ||
64 | + } else { | ||
65 | + res.end('Thingsboard server connection error: ' + err.code ? err.code : ''); | ||
66 | + } | ||
67 | + }); | ||
68 | + | ||
69 | + const root = path.join(webDir, 'public'); | ||
70 | + | ||
71 | + const staticDir = path.join(root, 'static'); | ||
72 | + | ||
73 | + app.all('/api/*', (req, res) => { | ||
74 | + logger.info(req.method + ' ' + req.originalUrl); | ||
75 | + apiProxy.web(req, res); | ||
76 | + }); | ||
77 | + | ||
78 | + app.all('/static/rulenode/*', (req, res) => { | ||
79 | + apiProxy.web(req, res); | ||
80 | + }); | ||
81 | + | ||
82 | + app.use(historyApiFallback()); | ||
83 | + | ||
84 | + app.use('/static', express.static(staticDir)); | ||
85 | + | ||
86 | + app.get('*', (req, res) => { | ||
87 | + apiProxy.web(req, res); | ||
88 | + }); | ||
89 | + | ||
90 | + server.on('upgrade', (req, socket, head) => { | ||
91 | + apiProxy.ws(req, socket, head); | ||
92 | + }); | ||
93 | + | ||
94 | + server.listen(bindPort, bindAddress, (error) => { | ||
95 | + if (error) { | ||
96 | + logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message); | ||
97 | + logger.error(error.stack); | ||
98 | + exit(-1); | ||
99 | + } else { | ||
100 | + logger.info('==> 🌎 Listening on port %s.', bindPort); | ||
101 | + logger.info('Started ThingsBoard Web UI Microservice.'); | ||
102 | + } | ||
103 | + }); | ||
104 | + | ||
105 | + } catch (e) { | ||
106 | + logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message); | ||
107 | + logger.error(e.stack); | ||
108 | + exit(-1); | ||
109 | + } | ||
110 | +})(); | ||
111 | + | ||
112 | +process.on('exit', function () { | ||
113 | + exit(0); | ||
114 | +}); | ||
115 | + | ||
116 | +function exit(status) { | ||
117 | + logger.info('Exiting with status: %d ...', status); | ||
118 | + if (server) { | ||
119 | + logger.info('Stopping HTTP Server...'); | ||
120 | + var _server = server; | ||
121 | + server = null; | ||
122 | + _server.close(() => { | ||
123 | + logger.info('HTTP Server stopped.'); | ||
124 | + process.exit(status); | ||
125 | + }); | ||
126 | + } else { | ||
127 | + process.exit(status); | ||
128 | + } | ||
129 | +} |
msa/web-ui/src/main/assembly/windows.xml
0 → 100644
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2018 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" | ||
19 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
20 | + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> | ||
21 | + <id>windows</id> | ||
22 | + | ||
23 | + <formats> | ||
24 | + <format>zip</format> | ||
25 | + </formats> | ||
26 | + | ||
27 | + <!-- Workaround to create logs directory --> | ||
28 | + <fileSets> | ||
29 | + <fileSet> | ||
30 | + <directory>${pkg.win.dist}</directory> | ||
31 | + <outputDirectory>logs</outputDirectory> | ||
32 | + <excludes> | ||
33 | + <exclude>*/**</exclude> | ||
34 | + </excludes> | ||
35 | + </fileSet> | ||
36 | + <fileSet> | ||
37 | + <directory>${pkg.win.dist}/conf</directory> | ||
38 | + <outputDirectory>conf</outputDirectory> | ||
39 | + <lineEnding>windows</lineEnding> | ||
40 | + </fileSet> | ||
41 | + <fileSet> | ||
42 | + <directory>${project.build.directory}/web</directory> | ||
43 | + <outputDirectory>web</outputDirectory> | ||
44 | + </fileSet> | ||
45 | + </fileSets> | ||
46 | + | ||
47 | + <files> | ||
48 | + <file> | ||
49 | + <source>${pkg.win.dist}/bin/${pkg.name}.exe</source> | ||
50 | + <outputDirectory>bin</outputDirectory> | ||
51 | + <destName>${pkg.name}.exe</destName> | ||
52 | + </file> | ||
53 | + <file> | ||
54 | + <source>${pkg.win.dist}/service.exe</source> | ||
55 | + <outputDirectory/> | ||
56 | + <destName>${pkg.name}.exe</destName> | ||
57 | + </file> | ||
58 | + <file> | ||
59 | + <source>${pkg.win.dist}/service.xml</source> | ||
60 | + <outputDirectory/> | ||
61 | + <destName>${pkg.name}.xml</destName> | ||
62 | + <lineEnding>windows</lineEnding> | ||
63 | + </file> | ||
64 | + <file> | ||
65 | + <source>${pkg.win.dist}/install.bat</source> | ||
66 | + <outputDirectory/> | ||
67 | + <lineEnding>windows</lineEnding> | ||
68 | + </file> | ||
69 | + <file> | ||
70 | + <source>${pkg.win.dist}/uninstall.bat</source> | ||
71 | + <outputDirectory/> | ||
72 | + <lineEnding>windows</lineEnding> | ||
73 | + </file> | ||
74 | + </files> | ||
75 | +</assembly> |
msa/web-ui/src/main/filters/unix.properties
0 → 100644
1 | +pkg.logFolder=${pkg.unixLogFolder} |
1 | +#!/bin/sh | ||
2 | + | ||
3 | +if ! getent group ${pkg.user} >/dev/null; then | ||
4 | + addgroup --system ${pkg.user} | ||
5 | +fi | ||
6 | + | ||
7 | +if ! getent passwd ${pkg.user} >/dev/null; then | ||
8 | + adduser --quiet \ | ||
9 | + --system \ | ||
10 | + --ingroup ${pkg.user} \ | ||
11 | + --quiet \ | ||
12 | + --disabled-login \ | ||
13 | + --disabled-password \ | ||
14 | + --home ${pkg.installFolder} \ | ||
15 | + --no-create-home \ | ||
16 | + -gecos "Thingsboard application" \ | ||
17 | + ${pkg.user} | ||
18 | +fi |
msa/web-ui/src/main/scripts/init/tb-web-ui
0 → 100644
1 | +#!/bin/bash | ||
2 | +# | ||
3 | + | ||
4 | + | ||
5 | +### BEGIN INIT INFO | ||
6 | +# Provides: tb-web-ui | ||
7 | +# Required-Start: $remote_fs $syslog $network | ||
8 | +# Required-Stop: $remote_fs $syslog $network | ||
9 | +# Default-Start: 2 3 4 5 | ||
10 | +# Default-Stop: 0 1 6 | ||
11 | +# Short-Description: ${project.name} | ||
12 | +# Description: ${project.description} | ||
13 | +# chkconfig: 2345 99 01 | ||
14 | +### END INIT INFO | ||
15 | + | ||
16 | +[[ -n "$DEBUG" ]] && set -x | ||
17 | + | ||
18 | +# Initialize variables that cannot be provided by a .conf file | ||
19 | +WORKING_DIR="$(pwd)" | ||
20 | +# shellcheck disable=SC2153 | ||
21 | + | ||
22 | +mainfile=${pkg.installFolder}/bin/${pkg.name} | ||
23 | +configfile=${pkg.name}.conf | ||
24 | + | ||
25 | +# Follow symlinks to find the real script and detect init.d script | ||
26 | +cd "$(dirname "$0")" || exit 1 | ||
27 | +[[ -z "$initfile" ]] && initfile=$(pwd)/$(basename "$0") | ||
28 | +while [[ -L "$initfile" ]]; do | ||
29 | + [[ "$initfile" =~ init\.d ]] && init_script=$(basename "$initfile") | ||
30 | + initfile=$(readlink "$initfile") | ||
31 | + cd "$(dirname "$initfile")" || exit 1 | ||
32 | + initfile=$(pwd)/$(basename "$initfile") | ||
33 | +done | ||
34 | +initfolder="$( (cd "$(dirname "initfile")" && pwd -P) )" | ||
35 | +cd "$WORKING_DIR" || exit 1 | ||
36 | + | ||
37 | +# Initialize CONF_FOLDER location | ||
38 | +[[ -z "$CONF_FOLDER" ]] && CONF_FOLDER="${pkg.installFolder}/conf" | ||
39 | + | ||
40 | +# shellcheck source=/dev/null | ||
41 | +[[ -r "${CONF_FOLDER}/${configfile}" ]] && source "${CONF_FOLDER}/${configfile}" | ||
42 | + | ||
43 | +# Initialize PID/LOG locations if they weren't provided by the config file | ||
44 | +[[ -z "$PID_FOLDER" ]] && PID_FOLDER="/var/run" | ||
45 | +[[ -z "$LOG_FOLDER" ]] && LOG_FOLDER="${pkg.unixLogFolder}" | ||
46 | +! [[ "$PID_FOLDER" == /* ]] && PID_FOLDER="$(dirname "$mainfile")"/"$PID_FOLDER" | ||
47 | +! [[ "$LOG_FOLDER" == /* ]] && LOG_FOLDER="$(dirname "$mainfile")"/"$LOG_FOLDER" | ||
48 | +! [[ -x "$PID_FOLDER" ]] && PID_FOLDER="/tmp" | ||
49 | +! [[ -x "$LOG_FOLDER" ]] && LOG_FOLDER="/tmp" | ||
50 | + | ||
51 | +# Set up defaults | ||
52 | +[[ -z "$MODE" ]] && MODE="auto" # modes are "auto", "service" or "run" | ||
53 | +[[ -z "$USE_START_STOP_DAEMON" ]] && USE_START_STOP_DAEMON="true" | ||
54 | + | ||
55 | +# Create an identity for log/pid files | ||
56 | +if [[ -z "$identity" ]]; then | ||
57 | + if [[ -n "$init_script" ]]; then | ||
58 | + identity="${init_script}" | ||
59 | + else | ||
60 | + identity=$(basename "${initfile%.*}")_${initfolder//\//} | ||
61 | + fi | ||
62 | +fi | ||
63 | + | ||
64 | +# Initialize log file name if not provided by the config file | ||
65 | +[[ -z "$LOG_FILENAME" ]] && LOG_FILENAME="${identity}.log" | ||
66 | + | ||
67 | +# ANSI Colors | ||
68 | +echoRed() { echo $'\e[0;31m'"$1"$'\e[0m'; } | ||
69 | +echoGreen() { echo $'\e[0;32m'"$1"$'\e[0m'; } | ||
70 | +echoYellow() { echo $'\e[0;33m'"$1"$'\e[0m'; } | ||
71 | + | ||
72 | +# Utility functions | ||
73 | +checkPermissions() { | ||
74 | + touch "$pid_file" &> /dev/null || { echoRed "Operation not permitted (cannot access pid file)"; return 4; } | ||
75 | + touch "$log_file" &> /dev/null || { echoRed "Operation not permitted (cannot access log file)"; return 4; } | ||
76 | +} | ||
77 | + | ||
78 | +isRunning() { | ||
79 | + ps -p "$1" &> /dev/null | ||
80 | +} | ||
81 | + | ||
82 | +await_file() { | ||
83 | + end=$(date +%s) | ||
84 | + let "end+=10" | ||
85 | + while [[ ! -s "$1" ]] | ||
86 | + do | ||
87 | + now=$(date +%s) | ||
88 | + if [[ $now -ge $end ]]; then | ||
89 | + break | ||
90 | + fi | ||
91 | + sleep 1 | ||
92 | + done | ||
93 | +} | ||
94 | + | ||
95 | +# Determine the script mode | ||
96 | +action="run" | ||
97 | +if [[ "$MODE" == "auto" && -n "$init_script" ]] || [[ "$MODE" == "service" ]]; then | ||
98 | + action="$1" | ||
99 | + shift | ||
100 | +fi | ||
101 | + | ||
102 | +# Build the pid and log filenames | ||
103 | +if [[ "$identity" == "$init_script" ]] || [[ "$identity" == "$APP_NAME" ]]; then | ||
104 | + PID_FOLDER="$PID_FOLDER/${identity}" | ||
105 | + pid_subfolder=$PID_FOLDER | ||
106 | +fi | ||
107 | +pid_file="$PID_FOLDER/${identity}.pid" | ||
108 | +log_file="$LOG_FOLDER/$LOG_FILENAME" | ||
109 | + | ||
110 | +# Determine the user to run as if we are root | ||
111 | +# shellcheck disable=SC2012 | ||
112 | +[[ $(id -u) == "0" ]] && run_user=$(ls -ld "$mainfile" | awk '{print $3}') | ||
113 | + | ||
114 | +arguments=($RUN_ARGS "$@") | ||
115 | + | ||
116 | +# Action functions | ||
117 | +start() { | ||
118 | + if [[ -f "$pid_file" ]]; then | ||
119 | + pid=$(cat "$pid_file") | ||
120 | + isRunning "$pid" && { echoYellow "Already running [$pid]"; return 0; } | ||
121 | + fi | ||
122 | + do_start "$@" | ||
123 | +} | ||
124 | + | ||
125 | +do_start() { | ||
126 | + working_dir=$(dirname "$mainfile") | ||
127 | + pushd "$working_dir" > /dev/null | ||
128 | + mkdir -p "$PID_FOLDER" &> /dev/null | ||
129 | + if [[ -n "$run_user" ]]; then | ||
130 | + checkPermissions || return $? | ||
131 | + if [[ -z "$pid_subfolder" ]]; then | ||
132 | + chown "$run_user" "$pid_subfolder" | ||
133 | + fi | ||
134 | + chown "$run_user" "$pid_file" | ||
135 | + chown "$run_user" "$log_file" | ||
136 | + if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then | ||
137 | + start-stop-daemon --start --quiet \ | ||
138 | + --chuid "$run_user" \ | ||
139 | + --name "$identity" \ | ||
140 | + --make-pidfile --pidfile "$pid_file" \ | ||
141 | + --background --no-close \ | ||
142 | + --startas "$mainfile" \ | ||
143 | + --chdir "$working_dir" \ | ||
144 | + -- "${arguments[@]}" \ | ||
145 | + >> "$log_file" 2>&1 | ||
146 | + await_file "$pid_file" | ||
147 | + else | ||
148 | + su -s /bin/sh -c "$mainfile $(printf "\"%s\" " "${arguments[@]}") >> \"$log_file\" 2>&1 & echo \$!" "$run_user" > "$pid_file" | ||
149 | + fi | ||
150 | + pid=$(cat "$pid_file") | ||
151 | + else | ||
152 | + checkPermissions || return $? | ||
153 | + "$mainfile" "${arguments[@]}" >> "$log_file" 2>&1 & | ||
154 | + pid=$! | ||
155 | + disown $pid | ||
156 | + echo "$pid" > "$pid_file" | ||
157 | + fi | ||
158 | + [[ -z $pid ]] && { echoRed "Failed to start"; return 1; } | ||
159 | + echoGreen "Started [$pid]" | ||
160 | +} | ||
161 | + | ||
162 | +stop() { | ||
163 | + working_dir=$(dirname "$mainfile") | ||
164 | + pushd "$working_dir" > /dev/null | ||
165 | + [[ -f $pid_file ]] || { echoYellow "Not running (pidfile not found)"; return 0; } | ||
166 | + pid=$(cat "$pid_file") | ||
167 | + isRunning "$pid" || { echoYellow "Not running (process ${pid}). Removing stale pid file."; rm -f "$pid_file"; return 0; } | ||
168 | + do_stop "$pid" "$pid_file" | ||
169 | +} | ||
170 | + | ||
171 | +do_stop() { | ||
172 | + kill -2 "$1" &> /dev/null || { echoRed "Unable to kill process $1"; return 1; } | ||
173 | + for i in $(seq 1 60); do | ||
174 | + isRunning "$1" || { echoGreen "Stopped [$1]"; rm -f "$2"; return 0; } | ||
175 | + [[ $i -eq 30 ]] && kill -9 "$1" &> /dev/null | ||
176 | + sleep 1 | ||
177 | + done | ||
178 | + echoRed "Unable to kill process $1"; | ||
179 | + return 1; | ||
180 | +} | ||
181 | + | ||
182 | +restart() { | ||
183 | + stop && start | ||
184 | +} | ||
185 | + | ||
186 | +orce_reload() { | ||
187 | + working_dir=$(dirname "$mainfile") | ||
188 | + pushd "$working_dir" > /dev/null | ||
189 | + [[ -f $pid_file ]] || { echoRed "Not running (pidfile not found)"; return 7; } | ||
190 | + pid=$(cat "$pid_file") | ||
191 | + rm -f "$pid_file" | ||
192 | + isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 7; } | ||
193 | + do_stop "$pid" "$pid_file" | ||
194 | + do_start | ||
195 | +} | ||
196 | + | ||
197 | +status() { | ||
198 | + working_dir=$(dirname "$mainfile") | ||
199 | + pushd "$working_dir" > /dev/null | ||
200 | + [[ -f "$pid_file" ]] || { echoRed "Not running"; return 3; } | ||
201 | + pid=$(cat "$pid_file") | ||
202 | + isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 1; } | ||
203 | + echoGreen "Running [$pid]" | ||
204 | + return 0 | ||
205 | +} | ||
206 | + | ||
207 | +run() { | ||
208 | + pushd "$(dirname "$mainfile")" > /dev/null | ||
209 | + "$mainfile" "${arguments[@]}" | ||
210 | + result=$? | ||
211 | + popd > /dev/null | ||
212 | + return "$result" | ||
213 | +} | ||
214 | + | ||
215 | +# Call the appropriate action function | ||
216 | +case "$action" in | ||
217 | +start) | ||
218 | + start "$@"; exit $?;; | ||
219 | +stop) | ||
220 | + stop "$@"; exit $?;; | ||
221 | +restart) | ||
222 | + restart "$@"; exit $?;; | ||
223 | +force-reload) | ||
224 | + force_reload "$@"; exit $?;; | ||
225 | +status) | ||
226 | + status "$@"; exit $?;; | ||
227 | +run) | ||
228 | + run "$@"; exit $?;; | ||
229 | +*) | ||
230 | + echo "Usage: $0 {start|stop|restart|force-reload|status|run}"; exit 1; | ||
231 | +esac | ||
232 | + | ||
233 | +exit 0 |
1 | +@REM | ||
2 | +@REM Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +@REM | ||
4 | +@REM Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +@REM you may not use this file except in compliance with the License. | ||
6 | +@REM You may obtain a copy of the License at | ||
7 | +@REM | ||
8 | +@REM http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +@REM | ||
10 | +@REM Unless required by applicable law or agreed to in writing, software | ||
11 | +@REM distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +@REM See the License for the specific language governing permissions and | ||
14 | +@REM limitations under the License. | ||
15 | +@REM | ||
16 | + | ||
17 | +@ECHO OFF | ||
18 | + | ||
19 | +setlocal ENABLEEXTENSIONS | ||
20 | + | ||
21 | +@ECHO Installing ${pkg.name} ... | ||
22 | + | ||
23 | +SET BASE=%~dp0 | ||
24 | + | ||
25 | +%BASE%${pkg.name}.exe install | ||
26 | + | ||
27 | +@ECHO ${pkg.name} installed successfully! | ||
28 | + | ||
29 | +GOTO END | ||
30 | + | ||
31 | +:END |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2018 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<service> | ||
19 | + <id>${pkg.name}</id> | ||
20 | + <name>${project.name}</name> | ||
21 | + <description>${project.description}</description> | ||
22 | + <workingdirectory>%BASE%\bin</workingdirectory> | ||
23 | + <logpath>${pkg.winWrapperLogFolder}</logpath> | ||
24 | + <logmode>rotate</logmode> | ||
25 | + <env name="NODE_CONFIG_DIR" value="%BASE%\conf" /> | ||
26 | + <env name="LOG_FOLDER" value="${pkg.winWrapperLogFolder}" /> | ||
27 | + <env name="NODE_ENV" value="production" /> | ||
28 | + <env name="WEB_FOLDER" value="%BASE%\web" /> | ||
29 | + <executable>%BASE%\bin\${pkg.name}.exe</executable> | ||
30 | +</service> |
1 | +@REM | ||
2 | +@REM Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +@REM | ||
4 | +@REM Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +@REM you may not use this file except in compliance with the License. | ||
6 | +@REM You may obtain a copy of the License at | ||
7 | +@REM | ||
8 | +@REM http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +@REM | ||
10 | +@REM Unless required by applicable law or agreed to in writing, software | ||
11 | +@REM distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +@REM See the License for the specific language governing permissions and | ||
14 | +@REM limitations under the License. | ||
15 | +@REM | ||
16 | + | ||
17 | +@ECHO OFF | ||
18 | + | ||
19 | +@ECHO Stopping ${pkg.name} ... | ||
20 | +net stop ${pkg.name} | ||
21 | + | ||
22 | +@ECHO Uninstalling ${pkg.name} ... | ||
23 | +%~dp0${pkg.name}.exe uninstall | ||
24 | + | ||
25 | +@ECHO DONE. |
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | "name": "thingsboard", | 2 | "name": "thingsboard", |
3 | "private": true, | 3 | "private": true, |
4 | "version": "2.2.0", | 4 | "version": "2.2.0", |
5 | - "description": "Thingsboard UI", | 5 | + "description": "ThingsBoard UI", |
6 | "licenses": [ | 6 | "licenses": [ |
7 | { | 7 | { |
8 | "type": "Apache-2.0", | 8 | "type": "Apache-2.0", |