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