32 changed files with 1421 additions and 2 deletions
@ -0,0 +1,9 @@ |
|||
|
|||
HTTP_BIND_ADDRESS=0.0.0.0 |
|||
HTTP_BIND_PORT=8090 |
|||
TB_HOST=localhost |
|||
TB_PORT=8080 |
|||
LOGGER_LEVEL=debug |
|||
LOG_FOLDER=logs |
|||
LOGGER_FILENAME=tb-web-ui-%DATE%.log |
|||
DOCKER_MODE=true |
|||
@ -0,0 +1,31 @@ |
|||
*.toDelete |
|||
output/** |
|||
*.class |
|||
*~ |
|||
*.iml |
|||
*/.idea/** |
|||
.idea/** |
|||
.idea |
|||
*.log |
|||
*.log.[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] |
|||
*/.classpath |
|||
.classpath |
|||
*/.project |
|||
.project |
|||
.cache/** |
|||
target/ |
|||
logs/ |
|||
build/ |
|||
.settings/ |
|||
/bin |
|||
bin/ |
|||
**/dependency-reduced-pom.xml |
|||
pom.xml.versionsBackup |
|||
.DS_Store |
|||
**/.gradle |
|||
**/local.properties |
|||
**/build |
|||
**/target |
|||
**/.env |
|||
node_modules |
|||
package-lock.json |
|||
@ -0,0 +1,125 @@ |
|||
/** |
|||
* Copyright © 2016-2018 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. |
|||
*/ |
|||
import org.apache.tools.ant.filters.ReplaceTokens |
|||
|
|||
buildscript { |
|||
ext { |
|||
osPackageVersion = "3.8.0" |
|||
} |
|||
repositories { |
|||
jcenter() |
|||
} |
|||
dependencies { |
|||
classpath("com.netflix.nebula:gradle-ospackage-plugin:${osPackageVersion}") |
|||
} |
|||
} |
|||
|
|||
apply plugin: "nebula.ospackage" |
|||
|
|||
buildDir = projectBuildDir |
|||
version = projectVersion |
|||
distsDirName = "./" |
|||
|
|||
// OS Package plugin configuration |
|||
ospackage { |
|||
packageName = pkgName |
|||
version = "${project.version}" |
|||
release = 1 |
|||
os = LINUX |
|||
type = BINARY |
|||
|
|||
into pkgInstallFolder |
|||
|
|||
user pkgUser |
|||
permissionGroup pkgUser |
|||
|
|||
// Copy the executable file |
|||
from("target/package/linux/bin/${pkgName}") { |
|||
fileMode 0500 |
|||
into "bin" |
|||
} |
|||
|
|||
// Copy the init file |
|||
from("target/package/linux/init/${pkgName}") { |
|||
fileMode 0500 |
|||
into "init" |
|||
} |
|||
|
|||
// Copy the config files |
|||
from("target/package/linux/conf") { |
|||
fileType CONFIG | NOREPLACE |
|||
fileMode 0754 |
|||
into "conf" |
|||
} |
|||
|
|||
// Copy web files |
|||
from("target/package/linux/web") { |
|||
into "web" |
|||
} |
|||
|
|||
} |
|||
|
|||
// Configure our RPM build task |
|||
buildRpm { |
|||
|
|||
arch = X86_64 |
|||
|
|||
version = projectVersion.replace('-', '') |
|||
archiveName = "${pkgName}.rpm" |
|||
|
|||
preInstall file("${buildDir}/control/rpm/preinst") |
|||
postInstall file("${buildDir}/control/rpm/postinst") |
|||
preUninstall file("${buildDir}/control/rpm/prerm") |
|||
postUninstall file("${buildDir}/control/rpm/postrm") |
|||
|
|||
user pkgUser |
|||
permissionGroup pkgUser |
|||
|
|||
// Copy the system unit files |
|||
from("${buildDir}/control/${pkgName}.service") { |
|||
addParentDirs = false |
|||
fileMode 0644 |
|||
into "/usr/lib/systemd/system" |
|||
} |
|||
|
|||
directory(pkgLogFolder, 0755) |
|||
link("/etc/${pkgName}/conf", "${pkgInstallFolder}/conf") |
|||
} |
|||
|
|||
// Same as the buildRpm task |
|||
buildDeb { |
|||
|
|||
arch = "amd64" |
|||
|
|||
archiveName = "${pkgName}.deb" |
|||
|
|||
configurationFile("${pkgInstallFolder}/conf/${pkgName}.conf") |
|||
configurationFile("${pkgInstallFolder}/conf/custom-environment-variables.yml") |
|||
configurationFile("${pkgInstallFolder}/conf/default.yml") |
|||
configurationFile("${pkgInstallFolder}/conf/logger.js") |
|||
|
|||
preInstall file("${buildDir}/control/deb/preinst") |
|||
postInstall file("${buildDir}/control/deb/postinst") |
|||
preUninstall file("${buildDir}/control/deb/prerm") |
|||
postUninstall file("${buildDir}/control/deb/postrm") |
|||
|
|||
user pkgUser |
|||
permissionGroup pkgUser |
|||
|
|||
directory(pkgLogFolder, 0755) |
|||
link("/etc/init.d/${pkgName}", "${pkgInstallFolder}/init/${pkgName}") |
|||
link("/etc/${pkgName}/conf", "${pkgInstallFolder}/conf") |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
# |
|||
# Copyright © 2016-2018 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. |
|||
# |
|||
|
|||
server: |
|||
# Server bind address |
|||
address: "HTTP_BIND_ADDRESS" |
|||
# Server bind port |
|||
port: "HTTP_BIND_PORT" |
|||
thingsboard: |
|||
# ThingsBoard node host |
|||
host: "TB_HOST" |
|||
# ThingsBoard node port |
|||
port: "TB_PORT" |
|||
logger: |
|||
level: "LOGGER_LEVEL" |
|||
path: "LOG_FOLDER" |
|||
filename: "LOGGER_FILENAME" |
|||
@ -0,0 +1,30 @@ |
|||
# |
|||
# Copyright © 2016-2018 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. |
|||
# |
|||
|
|||
server: |
|||
# Server bind address |
|||
address: "0.0.0.0" |
|||
# Server bind port |
|||
port: "8090" |
|||
thingsboard: |
|||
# ThingsBoard node host |
|||
host: "localhost" |
|||
# ThingsBoard node port |
|||
port: "8080" |
|||
logger: |
|||
level: "info" |
|||
path: "logs" |
|||
filename: "tb-web-ui-%DATE%.log" |
|||
@ -0,0 +1,59 @@ |
|||
/* |
|||
* Copyright © 2016-2018 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. |
|||
*/ |
|||
var config = require('config'), |
|||
path = require('path'), |
|||
DailyRotateFile = require('winston-daily-rotate-file'); |
|||
|
|||
const { createLogger, format, transports } = require('winston'); |
|||
const { combine, timestamp, label, printf, splat } = format; |
|||
|
|||
var loggerTransports = []; |
|||
|
|||
if (process.env.NODE_ENV !== 'production' || process.env.DOCKER_MODE === 'true') { |
|||
loggerTransports.push(new transports.Console({ |
|||
handleExceptions: true |
|||
})); |
|||
} else { |
|||
var filename = path.join(config.get('logger.path'), config.get('logger.filename')); |
|||
var transport = new (DailyRotateFile)({ |
|||
filename: filename, |
|||
datePattern: 'YYYY-MM-DD-HH', |
|||
zippedArchive: true, |
|||
maxSize: '20m', |
|||
maxFiles: '14d', |
|||
handleExceptions: true |
|||
}); |
|||
loggerTransports.push(transport); |
|||
} |
|||
|
|||
const tbFormat = printf(info => { |
|||
return `${info.timestamp} [${info.label}] ${info.level.toUpperCase()}: ${info.message}`; |
|||
}); |
|||
|
|||
function _logger(moduleLabel) { |
|||
return createLogger({ |
|||
level: config.get('logger.level'), |
|||
format:combine( |
|||
splat(), |
|||
label({ label: moduleLabel }), |
|||
timestamp({format: 'YYYY-MM-DD HH:mm:ss,SSS'}), |
|||
tbFormat |
|||
), |
|||
transports: loggerTransports |
|||
}); |
|||
} |
|||
|
|||
module.exports = _logger; |
|||
@ -0,0 +1,20 @@ |
|||
# |
|||
# Copyright © 2016-2018 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. |
|||
# |
|||
|
|||
export NODE_CONFIG_DIR=${pkg.installFolder}/conf |
|||
export LOG_FOLDER=${pkg.logFolder} |
|||
export NODE_ENV=production |
|||
export WEB_FOLDER=${pkg.installFolder}/web |
|||
@ -0,0 +1,26 @@ |
|||
# |
|||
# Copyright © 2016-2018 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. |
|||
# |
|||
|
|||
FROM debian:stretch |
|||
|
|||
COPY start-web-ui.sh ${pkg.name}.deb /tmp/ |
|||
|
|||
RUN chmod a+x /tmp/*.sh \ |
|||
&& mv /tmp/start-web-ui.sh /usr/bin |
|||
|
|||
RUN dpkg -i /tmp/${pkg.name}.deb |
|||
|
|||
CMD ["start-web-ui.sh"] |
|||
@ -0,0 +1,29 @@ |
|||
#!/bin/bash |
|||
# |
|||
# Copyright © 2016-2018 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. |
|||
# |
|||
|
|||
|
|||
echo "Starting '${project.name}' ..." |
|||
|
|||
CONF_FOLDER="${pkg.installFolder}/conf" |
|||
|
|||
mainfile=${pkg.installFolder}/bin/${pkg.name} |
|||
configfile=${pkg.name}.conf |
|||
identity=${pkg.name} |
|||
|
|||
source "${CONF_FOLDER}/${configfile}" |
|||
|
|||
su -s /bin/sh -c "$mainfile" |
|||
@ -0,0 +1,42 @@ |
|||
/* |
|||
* Copyright © 2016-2018 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. |
|||
*/ |
|||
const fs = require('fs'); |
|||
const fse = require('fs-extra'); |
|||
const path = require('path'); |
|||
|
|||
let _projectRoot = null; |
|||
|
|||
|
|||
(async() => { |
|||
await fse.move(path.join(projectRoot(), 'target', 'thingsboard-web-ui-linux'), |
|||
path.join(targetPackageDir('linux'), 'bin', 'tb-web-ui'), |
|||
{overwrite: true}); |
|||
await fse.move(path.join(projectRoot(), 'target', 'thingsboard-web-ui-win.exe'), |
|||
path.join(targetPackageDir('windows'), 'bin', 'tb-web-ui.exe'), |
|||
{overwrite: true}); |
|||
})(); |
|||
|
|||
|
|||
function projectRoot() { |
|||
if (!_projectRoot) { |
|||
_projectRoot = __dirname; |
|||
} |
|||
return _projectRoot; |
|||
} |
|||
|
|||
function targetPackageDir(platform) { |
|||
return path.join(projectRoot(), 'target', 'package', platform); |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
{ |
|||
"name": "thingsboard-web-ui", |
|||
"private": true, |
|||
"version": "2.2.0", |
|||
"description": "ThingsBoard Web UI Microservice", |
|||
"main": "server.js", |
|||
"bin": "server.js", |
|||
"scripts": { |
|||
"install": "pkg -t node8-linux-x64,node8-win-x64 --out-path ./target . && node install.js", |
|||
"test": "echo \"Error: no test specified\" && exit 1", |
|||
"start": "WEB_FOLDER=./target/web nodemon server.js", |
|||
"start-prod": "NODE_ENV=production nodemon server.js" |
|||
}, |
|||
"dependencies": { |
|||
"config": "^1.30.0", |
|||
"connect-history-api-fallback": "^1.5.0", |
|||
"express": "^4.16.3", |
|||
"http": "0.0.0", |
|||
"http-proxy": "^1.17.0", |
|||
"js-yaml": "^3.12.0", |
|||
"winston": "^3.0.0", |
|||
"winston-daily-rotate-file": "^3.2.1" |
|||
}, |
|||
"engine": "node >= 5.9.0", |
|||
"nyc": { |
|||
"exclude": [ |
|||
"test", |
|||
"__tests__", |
|||
"node_modules", |
|||
"target" |
|||
] |
|||
}, |
|||
"devDependencies": { |
|||
"fs-extra": "^6.0.1", |
|||
"nodemon": "^1.17.5", |
|||
"pkg": "^4.3.3" |
|||
} |
|||
} |
|||
@ -0,0 +1,372 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2018 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. |
|||
|
|||
--> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.thingsboard</groupId> |
|||
<version>2.2.0-SNAPSHOT</version> |
|||
<artifactId>msa</artifactId> |
|||
</parent> |
|||
<groupId>org.thingsboard.msa</groupId> |
|||
<artifactId>web-ui</artifactId> |
|||
<packaging>pom</packaging> |
|||
|
|||
<name>ThingsBoard Web UI Microservice</name> |
|||
<url>https://thingsboard.io</url> |
|||
<description>Service for hosting ThingsBoard Web UI</description> |
|||
|
|||
<properties> |
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
|||
<main.dir>${basedir}/../..</main.dir> |
|||
<pkg.name>tb-web-ui</pkg.name> |
|||
<pkg.user>thingsboard</pkg.user> |
|||
<pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder> |
|||
<pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> |
|||
<pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist> |
|||
<pkg.win.dist>${project.build.directory}/package/windows</pkg.win.dist> |
|||
<dockerfile.skip>true</dockerfile.skip> |
|||
</properties> |
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.thingsboard</groupId> |
|||
<artifactId>ui</artifactId> |
|||
<version>${project.version}</version> |
|||
<type>jar</type> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.sun.winsw</groupId> |
|||
<artifactId>winsw</artifactId> |
|||
<classifier>bin</classifier> |
|||
<type>exe</type> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>com.github.eirslett</groupId> |
|||
<artifactId>frontend-maven-plugin</artifactId> |
|||
<version>1.0</version> |
|||
<configuration> |
|||
<installDirectory>target</installDirectory> |
|||
<workingDirectory>${basedir}</workingDirectory> |
|||
</configuration> |
|||
<executions> |
|||
<execution> |
|||
<id>install node and npm</id> |
|||
<goals> |
|||
<goal>install-node-and-npm</goal> |
|||
</goals> |
|||
<configuration> |
|||
<nodeVersion>v8.11.3</nodeVersion> |
|||
<npmVersion>5.6.0</npmVersion> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>npm install</id> |
|||
<goals> |
|||
<goal>npm</goal> |
|||
</goals> |
|||
<configuration> |
|||
<arguments>install</arguments> |
|||
</configuration> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-dependency-plugin</artifactId> |
|||
<executions> |
|||
<execution> |
|||
<id>extract-web-ui</id> |
|||
<goals> |
|||
<goal>unpack</goal> |
|||
</goals> |
|||
<configuration> |
|||
<artifactItems> |
|||
<artifactItem> |
|||
<groupId>org.thingsboard</groupId> |
|||
<artifactId>ui</artifactId> |
|||
<type>jar</type> |
|||
<overWrite>false</overWrite> |
|||
<outputDirectory>${project.build.directory}/web</outputDirectory> |
|||
</artifactItem> |
|||
</artifactItems> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>copy-winsw-service</id> |
|||
<phase>package</phase> |
|||
<goals> |
|||
<goal>copy</goal> |
|||
</goals> |
|||
<configuration> |
|||
<artifactItems> |
|||
<artifactItem> |
|||
<groupId>com.sun.winsw</groupId> |
|||
<artifactId>winsw</artifactId> |
|||
<classifier>bin</classifier> |
|||
<type>exe</type> |
|||
<destFileName>service.exe</destFileName> |
|||
</artifactItem> |
|||
</artifactItems> |
|||
<outputDirectory>${pkg.win.dist}</outputDirectory> |
|||
</configuration> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-resources-plugin</artifactId> |
|||
<executions> |
|||
<execution> |
|||
<id>copy-linux-conf</id> |
|||
<phase>process-resources</phase> |
|||
<goals> |
|||
<goal>copy-resources</goal> |
|||
</goals> |
|||
<configuration> |
|||
<outputDirectory>${pkg.linux.dist}/conf</outputDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>config</directory> |
|||
<filtering>true</filtering> |
|||
</resource> |
|||
</resources> |
|||
<filters> |
|||
<filter>src/main/filters/unix.properties</filter> |
|||
</filters> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>copy-linux-init</id> |
|||
<phase>process-resources</phase> |
|||
<goals> |
|||
<goal>copy-resources</goal> |
|||
</goals> |
|||
<configuration> |
|||
<outputDirectory>${pkg.linux.dist}/init</outputDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>src/main/scripts/init</directory> |
|||
<filtering>true</filtering> |
|||
</resource> |
|||
</resources> |
|||
<filters> |
|||
<filter>src/main/filters/unix.properties</filter> |
|||
</filters> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>copy-win-conf</id> |
|||
<phase>process-resources</phase> |
|||
<goals> |
|||
<goal>copy-resources</goal> |
|||
</goals> |
|||
<configuration> |
|||
<outputDirectory>${pkg.win.dist}/conf</outputDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>config</directory> |
|||
<excludes> |
|||
<exclude>tb-web-ui.conf</exclude> |
|||
</excludes> |
|||
<filtering>true</filtering> |
|||
</resource> |
|||
</resources> |
|||
<filters> |
|||
<filter>src/main/filters/windows.properties</filter> |
|||
</filters> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>copy-control</id> |
|||
<phase>process-resources</phase> |
|||
<goals> |
|||
<goal>copy-resources</goal> |
|||
</goals> |
|||
<configuration> |
|||
<outputDirectory>${project.build.directory}/control</outputDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>src/main/scripts/control</directory> |
|||
<filtering>true</filtering> |
|||
</resource> |
|||
</resources> |
|||
<filters> |
|||
<filter>src/main/filters/unix.properties</filter> |
|||
</filters> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>copy-windows-control</id> |
|||
<phase>process-resources</phase> |
|||
<goals> |
|||
<goal>copy-resources</goal> |
|||
</goals> |
|||
<configuration> |
|||
<outputDirectory>${pkg.win.dist}</outputDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>src/main/scripts/windows</directory> |
|||
<filtering>true</filtering> |
|||
</resource> |
|||
</resources> |
|||
<filters> |
|||
<filter>src/main/filters/windows.properties</filter> |
|||
</filters> |
|||
</configuration> |
|||
</execution> |
|||
<execution> |
|||
<id>copy-docker-config</id> |
|||
<phase>process-resources</phase> |
|||
<goals> |
|||
<goal>copy-resources</goal> |
|||
</goals> |
|||
<configuration> |
|||
<outputDirectory>${project.build.directory}</outputDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>docker</directory> |
|||
<filtering>true</filtering> |
|||
</resource> |
|||
</resources> |
|||
</configuration> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.fortasoft</groupId> |
|||
<artifactId>gradle-maven-plugin</artifactId> |
|||
<configuration> |
|||
<tasks> |
|||
<task>build</task> |
|||
<task>buildDeb</task> |
|||
<task>buildRpm</task> |
|||
</tasks> |
|||
<args> |
|||
<arg>-PprojectBuildDir=${project.build.directory}</arg> |
|||
<arg>-PprojectVersion=${project.version}</arg> |
|||
<arg>-PpkgName=${pkg.name}</arg> |
|||
<arg>-PpkgUser=${pkg.user}</arg> |
|||
<arg>-PpkgInstallFolder=${pkg.installFolder}</arg> |
|||
<arg>-PpkgLogFolder=${pkg.unixLogFolder}</arg> |
|||
</args> |
|||
</configuration> |
|||
<executions> |
|||
<execution> |
|||
<phase>package</phase> |
|||
<goals> |
|||
<goal>invoke</goal> |
|||
</goals> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-assembly-plugin</artifactId> |
|||
<version>3.0.0</version> |
|||
<configuration> |
|||
<finalName>${pkg.name}</finalName> |
|||
<descriptors> |
|||
<descriptor>src/main/assembly/windows.xml</descriptor> |
|||
</descriptors> |
|||
</configuration> |
|||
<executions> |
|||
<execution> |
|||
<id>assembly</id> |
|||
<phase>package</phase> |
|||
<goals> |
|||
<goal>single</goal> |
|||
</goals> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>com.spotify</groupId> |
|||
<artifactId>dockerfile-maven-plugin</artifactId> |
|||
<version>1.4.4</version> |
|||
<executions> |
|||
<execution> |
|||
<id>build-docker-image</id> |
|||
<phase>pre-integration-test</phase> |
|||
<goals> |
|||
<goal>build</goal> |
|||
</goals> |
|||
</execution> |
|||
</executions> |
|||
<configuration> |
|||
<skip>${dockerfile.skip}</skip> |
|||
<repository>local-maven-build/${pkg.name}</repository> |
|||
<verbose>true</verbose> |
|||
<googleContainerRegistryEnabled>false</googleContainerRegistryEnabled> |
|||
<contextDirectory>${project.build.directory}</contextDirectory> |
|||
</configuration> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
<profiles> |
|||
<profile> |
|||
<id>npm-start</id> |
|||
<activation> |
|||
<property> |
|||
<name>npm-start</name> |
|||
</property> |
|||
</activation> |
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>com.github.eirslett</groupId> |
|||
<artifactId>frontend-maven-plugin</artifactId> |
|||
<version>1.0</version> |
|||
<configuration> |
|||
<installDirectory>target</installDirectory> |
|||
<workingDirectory>${basedir}</workingDirectory> |
|||
</configuration> |
|||
<executions> |
|||
<execution> |
|||
<id>npm start</id> |
|||
<goals> |
|||
<goal>npm</goal> |
|||
</goals> |
|||
|
|||
<configuration> |
|||
<arguments>start</arguments> |
|||
</configuration> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
</profile> |
|||
</profiles> |
|||
<repositories> |
|||
<repository> |
|||
<id>jenkins</id> |
|||
<name>Jenkins Repository</name> |
|||
<url>http://repo.jenkins-ci.org/releases</url> |
|||
<snapshots> |
|||
<enabled>false</enabled> |
|||
</snapshots> |
|||
</repository> |
|||
</repositories> |
|||
</project> |
|||
@ -0,0 +1,129 @@ |
|||
/* |
|||
* Copyright © 2016-2018 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. |
|||
*/ |
|||
|
|||
const config = require('config'), |
|||
logger = require('./config/logger')('main'), |
|||
express = require('express'), |
|||
http = require('http'), |
|||
httpProxy = require('http-proxy'), |
|||
path = require('path'), |
|||
historyApiFallback = require("connect-history-api-fallback"); |
|||
|
|||
var server; |
|||
|
|||
(async() => { |
|||
try { |
|||
logger.info('Starting ThingsBoard Web UI Microservice...'); |
|||
|
|||
const bindAddress = config.get('server.address'); |
|||
const bindPort = config.get('server.port'); |
|||
|
|||
const thingsboardHost = config.get('thingsboard.host'); |
|||
const thingsboardPort = config.get('thingsboard.port'); |
|||
|
|||
logger.info('Bind address: %s', bindAddress); |
|||
logger.info('Bind port: %s', bindPort); |
|||
logger.info('ThingsBoard host: %s', thingsboardHost); |
|||
logger.info('ThingsBoard port: %s', thingsboardPort); |
|||
|
|||
var webDir = path.join(__dirname, 'web'); |
|||
|
|||
if (typeof process.env.WEB_FOLDER === 'string') { |
|||
webDir = path.resolve(process.env.WEB_FOLDER); |
|||
} |
|||
logger.info('Web folder: %s', webDir); |
|||
|
|||
const app = express(); |
|||
server = http.createServer(app); |
|||
|
|||
const apiProxy = httpProxy.createProxyServer({ |
|||
target: { |
|||
host: thingsboardHost, |
|||
port: thingsboardPort |
|||
} |
|||
}); |
|||
|
|||
apiProxy.on('error', function (err, req, res) { |
|||
logger.warn('API proxy error: %s', err.message); |
|||
res.writeHead(500); |
|||
if (err.code && err.code === 'ECONNREFUSED') { |
|||
res.end('Unable to connect to ThingsBoard server.'); |
|||
} else { |
|||
res.end('Thingsboard server connection error: ' + err.code ? err.code : ''); |
|||
} |
|||
}); |
|||
|
|||
const root = path.join(webDir, 'public'); |
|||
|
|||
const staticDir = path.join(root, 'static'); |
|||
|
|||
app.all('/api/*', (req, res) => { |
|||
logger.info(req.method + ' ' + req.originalUrl); |
|||
apiProxy.web(req, res); |
|||
}); |
|||
|
|||
app.all('/static/rulenode/*', (req, res) => { |
|||
apiProxy.web(req, res); |
|||
}); |
|||
|
|||
app.use(historyApiFallback()); |
|||
|
|||
app.use('/static', express.static(staticDir)); |
|||
|
|||
app.get('*', (req, res) => { |
|||
apiProxy.web(req, res); |
|||
}); |
|||
|
|||
server.on('upgrade', (req, socket, head) => { |
|||
apiProxy.ws(req, socket, head); |
|||
}); |
|||
|
|||
server.listen(bindPort, bindAddress, (error) => { |
|||
if (error) { |
|||
logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message); |
|||
logger.error(error.stack); |
|||
exit(-1); |
|||
} else { |
|||
logger.info('==> 🌎 Listening on port %s.', bindPort); |
|||
logger.info('Started ThingsBoard Web UI Microservice.'); |
|||
} |
|||
}); |
|||
|
|||
} catch (e) { |
|||
logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message); |
|||
logger.error(e.stack); |
|||
exit(-1); |
|||
} |
|||
})(); |
|||
|
|||
process.on('exit', function () { |
|||
exit(0); |
|||
}); |
|||
|
|||
function exit(status) { |
|||
logger.info('Exiting with status: %d ...', status); |
|||
if (server) { |
|||
logger.info('Stopping HTTP Server...'); |
|||
var _server = server; |
|||
server = null; |
|||
_server.close(() => { |
|||
logger.info('HTTP Server stopped.'); |
|||
process.exit(status); |
|||
}); |
|||
} else { |
|||
process.exit(status); |
|||
} |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2018 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. |
|||
|
|||
--> |
|||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" |
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> |
|||
<id>windows</id> |
|||
|
|||
<formats> |
|||
<format>zip</format> |
|||
</formats> |
|||
|
|||
<!-- Workaround to create logs directory --> |
|||
<fileSets> |
|||
<fileSet> |
|||
<directory>${pkg.win.dist}</directory> |
|||
<outputDirectory>logs</outputDirectory> |
|||
<excludes> |
|||
<exclude>*/**</exclude> |
|||
</excludes> |
|||
</fileSet> |
|||
<fileSet> |
|||
<directory>${pkg.win.dist}/conf</directory> |
|||
<outputDirectory>conf</outputDirectory> |
|||
<lineEnding>windows</lineEnding> |
|||
</fileSet> |
|||
<fileSet> |
|||
<directory>${project.build.directory}/web</directory> |
|||
<outputDirectory>web</outputDirectory> |
|||
</fileSet> |
|||
</fileSets> |
|||
|
|||
<files> |
|||
<file> |
|||
<source>${pkg.win.dist}/bin/${pkg.name}.exe</source> |
|||
<outputDirectory>bin</outputDirectory> |
|||
<destName>${pkg.name}.exe</destName> |
|||
</file> |
|||
<file> |
|||
<source>${pkg.win.dist}/service.exe</source> |
|||
<outputDirectory/> |
|||
<destName>${pkg.name}.exe</destName> |
|||
</file> |
|||
<file> |
|||
<source>${pkg.win.dist}/service.xml</source> |
|||
<outputDirectory/> |
|||
<destName>${pkg.name}.xml</destName> |
|||
<lineEnding>windows</lineEnding> |
|||
</file> |
|||
<file> |
|||
<source>${pkg.win.dist}/install.bat</source> |
|||
<outputDirectory/> |
|||
<lineEnding>windows</lineEnding> |
|||
</file> |
|||
<file> |
|||
<source>${pkg.win.dist}/uninstall.bat</source> |
|||
<outputDirectory/> |
|||
<lineEnding>windows</lineEnding> |
|||
</file> |
|||
</files> |
|||
</assembly> |
|||
@ -0,0 +1 @@ |
|||
pkg.logFolder=${pkg.unixLogFolder} |
|||
@ -0,0 +1,2 @@ |
|||
pkg.logFolder=${BASE}\\logs |
|||
pkg.winWrapperLogFolder=%BASE%\\logs |
|||
@ -0,0 +1,6 @@ |
|||
#!/bin/sh |
|||
|
|||
chown -R ${pkg.user}: ${pkg.logFolder} |
|||
chown -R ${pkg.user}: ${pkg.installFolder} |
|||
# update-rc.d ${pkg.name} defaults |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
#!/bin/sh |
|||
|
|||
update-rc.d -f ${pkg.name} remove |
|||
@ -0,0 +1,18 @@ |
|||
#!/bin/sh |
|||
|
|||
if ! getent group ${pkg.user} >/dev/null; then |
|||
addgroup --system ${pkg.user} |
|||
fi |
|||
|
|||
if ! getent passwd ${pkg.user} >/dev/null; then |
|||
adduser --quiet \ |
|||
--system \ |
|||
--ingroup ${pkg.user} \ |
|||
--quiet \ |
|||
--disabled-login \ |
|||
--disabled-password \ |
|||
--home ${pkg.installFolder} \ |
|||
--no-create-home \ |
|||
-gecos "Thingsboard application" \ |
|||
${pkg.user} |
|||
fi |
|||
@ -0,0 +1,5 @@ |
|||
#!/bin/sh |
|||
|
|||
if [ -e /var/run/${pkg.name}/${pkg.name}.pid ]; then |
|||
service ${pkg.name} stop |
|||
fi |
|||
@ -0,0 +1,9 @@ |
|||
#!/bin/sh |
|||
|
|||
chown -R ${pkg.user}: ${pkg.logFolder} |
|||
chown -R ${pkg.user}: ${pkg.installFolder} |
|||
|
|||
if [ $1 -eq 1 ] ; then |
|||
# Initial installation |
|||
systemctl --no-reload enable ${pkg.name}.service >/dev/null 2>&1 || : |
|||
fi |
|||
@ -0,0 +1,6 @@ |
|||
#!/bin/sh |
|||
|
|||
if [ $1 -ge 1 ] ; then |
|||
# Package upgrade, not uninstall |
|||
systemctl try-restart ${pkg.name}.service >/dev/null 2>&1 || : |
|||
fi |
|||
@ -0,0 +1,6 @@ |
|||
#!/bin/sh |
|||
|
|||
getent group ${pkg.user} >/dev/null || groupadd -r ${pkg.user} |
|||
getent passwd ${pkg.user} >/dev/null || \ |
|||
useradd -d ${pkg.installFolder} -g ${pkg.user} -M -r ${pkg.user} -s /sbin/nologin \ |
|||
-c "Thingsboard application" |
|||
@ -0,0 +1,6 @@ |
|||
#!/bin/sh |
|||
|
|||
if [ $1 -eq 0 ] ; then |
|||
# Package removal, not upgrade |
|||
systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : |
|||
fi |
|||
@ -0,0 +1,11 @@ |
|||
[Unit] |
|||
Description=${pkg.name} |
|||
After=syslog.target |
|||
|
|||
[Service] |
|||
User=${pkg.user} |
|||
ExecStart=${pkg.installFolder}/init/${pkg.name} |
|||
SuccessExitStatus=143 |
|||
|
|||
[Install] |
|||
WantedBy=multi-user.target |
|||
@ -0,0 +1,233 @@ |
|||
#!/bin/bash |
|||
# |
|||
|
|||
|
|||
### BEGIN INIT INFO |
|||
# Provides: tb-web-ui |
|||
# Required-Start: $remote_fs $syslog $network |
|||
# Required-Stop: $remote_fs $syslog $network |
|||
# Default-Start: 2 3 4 5 |
|||
# Default-Stop: 0 1 6 |
|||
# Short-Description: ${project.name} |
|||
# Description: ${project.description} |
|||
# chkconfig: 2345 99 01 |
|||
### END INIT INFO |
|||
|
|||
[[ -n "$DEBUG" ]] && set -x |
|||
|
|||
# Initialize variables that cannot be provided by a .conf file |
|||
WORKING_DIR="$(pwd)" |
|||
# shellcheck disable=SC2153 |
|||
|
|||
mainfile=${pkg.installFolder}/bin/${pkg.name} |
|||
configfile=${pkg.name}.conf |
|||
|
|||
# Follow symlinks to find the real script and detect init.d script |
|||
cd "$(dirname "$0")" || exit 1 |
|||
[[ -z "$initfile" ]] && initfile=$(pwd)/$(basename "$0") |
|||
while [[ -L "$initfile" ]]; do |
|||
[[ "$initfile" =~ init\.d ]] && init_script=$(basename "$initfile") |
|||
initfile=$(readlink "$initfile") |
|||
cd "$(dirname "$initfile")" || exit 1 |
|||
initfile=$(pwd)/$(basename "$initfile") |
|||
done |
|||
initfolder="$( (cd "$(dirname "initfile")" && pwd -P) )" |
|||
cd "$WORKING_DIR" || exit 1 |
|||
|
|||
# Initialize CONF_FOLDER location |
|||
[[ -z "$CONF_FOLDER" ]] && CONF_FOLDER="${pkg.installFolder}/conf" |
|||
|
|||
# shellcheck source=/dev/null |
|||
[[ -r "${CONF_FOLDER}/${configfile}" ]] && source "${CONF_FOLDER}/${configfile}" |
|||
|
|||
# Initialize PID/LOG locations if they weren't provided by the config file |
|||
[[ -z "$PID_FOLDER" ]] && PID_FOLDER="/var/run" |
|||
[[ -z "$LOG_FOLDER" ]] && LOG_FOLDER="${pkg.unixLogFolder}" |
|||
! [[ "$PID_FOLDER" == /* ]] && PID_FOLDER="$(dirname "$mainfile")"/"$PID_FOLDER" |
|||
! [[ "$LOG_FOLDER" == /* ]] && LOG_FOLDER="$(dirname "$mainfile")"/"$LOG_FOLDER" |
|||
! [[ -x "$PID_FOLDER" ]] && PID_FOLDER="/tmp" |
|||
! [[ -x "$LOG_FOLDER" ]] && LOG_FOLDER="/tmp" |
|||
|
|||
# Set up defaults |
|||
[[ -z "$MODE" ]] && MODE="auto" # modes are "auto", "service" or "run" |
|||
[[ -z "$USE_START_STOP_DAEMON" ]] && USE_START_STOP_DAEMON="true" |
|||
|
|||
# Create an identity for log/pid files |
|||
if [[ -z "$identity" ]]; then |
|||
if [[ -n "$init_script" ]]; then |
|||
identity="${init_script}" |
|||
else |
|||
identity=$(basename "${initfile%.*}")_${initfolder//\//} |
|||
fi |
|||
fi |
|||
|
|||
# Initialize log file name if not provided by the config file |
|||
[[ -z "$LOG_FILENAME" ]] && LOG_FILENAME="${identity}.log" |
|||
|
|||
# ANSI Colors |
|||
echoRed() { echo $'\e[0;31m'"$1"$'\e[0m'; } |
|||
echoGreen() { echo $'\e[0;32m'"$1"$'\e[0m'; } |
|||
echoYellow() { echo $'\e[0;33m'"$1"$'\e[0m'; } |
|||
|
|||
# Utility functions |
|||
checkPermissions() { |
|||
touch "$pid_file" &> /dev/null || { echoRed "Operation not permitted (cannot access pid file)"; return 4; } |
|||
touch "$log_file" &> /dev/null || { echoRed "Operation not permitted (cannot access log file)"; return 4; } |
|||
} |
|||
|
|||
isRunning() { |
|||
ps -p "$1" &> /dev/null |
|||
} |
|||
|
|||
await_file() { |
|||
end=$(date +%s) |
|||
let "end+=10" |
|||
while [[ ! -s "$1" ]] |
|||
do |
|||
now=$(date +%s) |
|||
if [[ $now -ge $end ]]; then |
|||
break |
|||
fi |
|||
sleep 1 |
|||
done |
|||
} |
|||
|
|||
# Determine the script mode |
|||
action="run" |
|||
if [[ "$MODE" == "auto" && -n "$init_script" ]] || [[ "$MODE" == "service" ]]; then |
|||
action="$1" |
|||
shift |
|||
fi |
|||
|
|||
# Build the pid and log filenames |
|||
if [[ "$identity" == "$init_script" ]] || [[ "$identity" == "$APP_NAME" ]]; then |
|||
PID_FOLDER="$PID_FOLDER/${identity}" |
|||
pid_subfolder=$PID_FOLDER |
|||
fi |
|||
pid_file="$PID_FOLDER/${identity}.pid" |
|||
log_file="$LOG_FOLDER/$LOG_FILENAME" |
|||
|
|||
# Determine the user to run as if we are root |
|||
# shellcheck disable=SC2012 |
|||
[[ $(id -u) == "0" ]] && run_user=$(ls -ld "$mainfile" | awk '{print $3}') |
|||
|
|||
arguments=($RUN_ARGS "$@") |
|||
|
|||
# Action functions |
|||
start() { |
|||
if [[ -f "$pid_file" ]]; then |
|||
pid=$(cat "$pid_file") |
|||
isRunning "$pid" && { echoYellow "Already running [$pid]"; return 0; } |
|||
fi |
|||
do_start "$@" |
|||
} |
|||
|
|||
do_start() { |
|||
working_dir=$(dirname "$mainfile") |
|||
pushd "$working_dir" > /dev/null |
|||
mkdir -p "$PID_FOLDER" &> /dev/null |
|||
if [[ -n "$run_user" ]]; then |
|||
checkPermissions || return $? |
|||
if [[ -z "$pid_subfolder" ]]; then |
|||
chown "$run_user" "$pid_subfolder" |
|||
fi |
|||
chown "$run_user" "$pid_file" |
|||
chown "$run_user" "$log_file" |
|||
if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then |
|||
start-stop-daemon --start --quiet \ |
|||
--chuid "$run_user" \ |
|||
--name "$identity" \ |
|||
--make-pidfile --pidfile "$pid_file" \ |
|||
--background --no-close \ |
|||
--startas "$mainfile" \ |
|||
--chdir "$working_dir" \ |
|||
-- "${arguments[@]}" \ |
|||
>> "$log_file" 2>&1 |
|||
await_file "$pid_file" |
|||
else |
|||
su -s /bin/sh -c "$mainfile $(printf "\"%s\" " "${arguments[@]}") >> \"$log_file\" 2>&1 & echo \$!" "$run_user" > "$pid_file" |
|||
fi |
|||
pid=$(cat "$pid_file") |
|||
else |
|||
checkPermissions || return $? |
|||
"$mainfile" "${arguments[@]}" >> "$log_file" 2>&1 & |
|||
pid=$! |
|||
disown $pid |
|||
echo "$pid" > "$pid_file" |
|||
fi |
|||
[[ -z $pid ]] && { echoRed "Failed to start"; return 1; } |
|||
echoGreen "Started [$pid]" |
|||
} |
|||
|
|||
stop() { |
|||
working_dir=$(dirname "$mainfile") |
|||
pushd "$working_dir" > /dev/null |
|||
[[ -f $pid_file ]] || { echoYellow "Not running (pidfile not found)"; return 0; } |
|||
pid=$(cat "$pid_file") |
|||
isRunning "$pid" || { echoYellow "Not running (process ${pid}). Removing stale pid file."; rm -f "$pid_file"; return 0; } |
|||
do_stop "$pid" "$pid_file" |
|||
} |
|||
|
|||
do_stop() { |
|||
kill -2 "$1" &> /dev/null || { echoRed "Unable to kill process $1"; return 1; } |
|||
for i in $(seq 1 60); do |
|||
isRunning "$1" || { echoGreen "Stopped [$1]"; rm -f "$2"; return 0; } |
|||
[[ $i -eq 30 ]] && kill -9 "$1" &> /dev/null |
|||
sleep 1 |
|||
done |
|||
echoRed "Unable to kill process $1"; |
|||
return 1; |
|||
} |
|||
|
|||
restart() { |
|||
stop && start |
|||
} |
|||
|
|||
orce_reload() { |
|||
working_dir=$(dirname "$mainfile") |
|||
pushd "$working_dir" > /dev/null |
|||
[[ -f $pid_file ]] || { echoRed "Not running (pidfile not found)"; return 7; } |
|||
pid=$(cat "$pid_file") |
|||
rm -f "$pid_file" |
|||
isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 7; } |
|||
do_stop "$pid" "$pid_file" |
|||
do_start |
|||
} |
|||
|
|||
status() { |
|||
working_dir=$(dirname "$mainfile") |
|||
pushd "$working_dir" > /dev/null |
|||
[[ -f "$pid_file" ]] || { echoRed "Not running"; return 3; } |
|||
pid=$(cat "$pid_file") |
|||
isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 1; } |
|||
echoGreen "Running [$pid]" |
|||
return 0 |
|||
} |
|||
|
|||
run() { |
|||
pushd "$(dirname "$mainfile")" > /dev/null |
|||
"$mainfile" "${arguments[@]}" |
|||
result=$? |
|||
popd > /dev/null |
|||
return "$result" |
|||
} |
|||
|
|||
# Call the appropriate action function |
|||
case "$action" in |
|||
start) |
|||
start "$@"; exit $?;; |
|||
stop) |
|||
stop "$@"; exit $?;; |
|||
restart) |
|||
restart "$@"; exit $?;; |
|||
force-reload) |
|||
force_reload "$@"; exit $?;; |
|||
status) |
|||
status "$@"; exit $?;; |
|||
run) |
|||
run "$@"; exit $?;; |
|||
*) |
|||
echo "Usage: $0 {start|stop|restart|force-reload|status|run}"; exit 1; |
|||
esac |
|||
|
|||
exit 0 |
|||
@ -0,0 +1,31 @@ |
|||
@REM |
|||
@REM Copyright © 2016-2018 The Thingsboard Authors |
|||
@REM |
|||
@REM Licensed under the Apache License, Version 2.0 (the "License"); |
|||
@REM you may not use this file except in compliance with the License. |
|||
@REM You may obtain a copy of the License at |
|||
@REM |
|||
@REM http://www.apache.org/licenses/LICENSE-2.0 |
|||
@REM |
|||
@REM Unless required by applicable law or agreed to in writing, software |
|||
@REM distributed under the License is distributed on an "AS IS" BASIS, |
|||
@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
@REM See the License for the specific language governing permissions and |
|||
@REM limitations under the License. |
|||
@REM |
|||
|
|||
@ECHO OFF |
|||
|
|||
setlocal ENABLEEXTENSIONS |
|||
|
|||
@ECHO Installing ${pkg.name} ... |
|||
|
|||
SET BASE=%~dp0 |
|||
|
|||
%BASE%${pkg.name}.exe install |
|||
|
|||
@ECHO ${pkg.name} installed successfully! |
|||
|
|||
GOTO END |
|||
|
|||
:END |
|||
@ -0,0 +1,30 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2018 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. |
|||
|
|||
--> |
|||
<service> |
|||
<id>${pkg.name}</id> |
|||
<name>${project.name}</name> |
|||
<description>${project.description}</description> |
|||
<workingdirectory>%BASE%\bin</workingdirectory> |
|||
<logpath>${pkg.winWrapperLogFolder}</logpath> |
|||
<logmode>rotate</logmode> |
|||
<env name="NODE_CONFIG_DIR" value="%BASE%\conf" /> |
|||
<env name="LOG_FOLDER" value="${pkg.winWrapperLogFolder}" /> |
|||
<env name="NODE_ENV" value="production" /> |
|||
<env name="WEB_FOLDER" value="%BASE%\web" /> |
|||
<executable>%BASE%\bin\${pkg.name}.exe</executable> |
|||
</service> |
|||
@ -0,0 +1,25 @@ |
|||
@REM |
|||
@REM Copyright © 2016-2018 The Thingsboard Authors |
|||
@REM |
|||
@REM Licensed under the Apache License, Version 2.0 (the "License"); |
|||
@REM you may not use this file except in compliance with the License. |
|||
@REM You may obtain a copy of the License at |
|||
@REM |
|||
@REM http://www.apache.org/licenses/LICENSE-2.0 |
|||
@REM |
|||
@REM Unless required by applicable law or agreed to in writing, software |
|||
@REM distributed under the License is distributed on an "AS IS" BASIS, |
|||
@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
@REM See the License for the specific language governing permissions and |
|||
@REM limitations under the License. |
|||
@REM |
|||
|
|||
@ECHO OFF |
|||
|
|||
@ECHO Stopping ${pkg.name} ... |
|||
net stop ${pkg.name} |
|||
|
|||
@ECHO Uninstalling ${pkg.name} ... |
|||
%~dp0${pkg.name}.exe uninstall |
|||
|
|||
@ECHO DONE. |
|||
Loading…
Reference in new issue