diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..4d6257a33 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,174 @@ +version: 2.1 + +############################################################################ + +references: + checkout_job_steps: &checkout_job_steps + steps: + - checkout + - run: + name: Checking out dependencies + command: | + git clone -b develop --single-branch https://github.com/Zimbra/zm-pkg-tool.git ~/zm-pkg-tool + echo "BUILD_NO=$CIRCLE_BUILD_NUM" > config.build + - persist_to_workspace: + root: .. + paths: + - zm-onlyoffice + - zm-pkg-tool + + build_job_steps: &build_job_steps + steps: + - attach_workspace: + at: .. + - run: + name: Creating build + command: make -f Makefile.build + no_output_timeout: 30m + - store_artifacts: + path: build/dist + - persist_to_workspace: + root: .. + paths: zm-onlyoffice/build/dist/* + + deploy_s3_job_steps: &deploy_s3_job_steps + docker: + - image: 'cimg/python:3.10' + resource_class: small + steps: + - attach_workspace: + at: .. + - run: + name: Create a zip file for artifacts and upload them to the OCI bucket + command: | + cd build/dist/ + zip -r $CIRCLE_PROJECT_REPONAME.zip . + ZIP_FILE_PATH="$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BRANCH-$CIRCLE_BUILD_NUM/archives/$CIRCLE_PROJECT_REPONAME.zip" + curl -X PUT "$OCI_PAR_URL$ZIP_FILE_PATH" -T $CIRCLE_PROJECT_REPONAME.zip + echo "artifacts uploaded to $ZIP_FILE_PATH" + + std_filters: &std_filters + filters: + branches: + only: + - master + - develop + +############################################################################ + +jobs: + checkout: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: zimbra/zm-base-os:core-ubuntu + resource_class: small + <<: *checkout_job_steps + + build_u22: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: $DOCKER_REGISTRY/zm-base-os:devcore-ubuntu-22.04 + auth: + username: $DOCKER_USER + password: $DOCKER_PASS + resource_class: small + <<: *build_job_steps + + build_u20: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: zimbra/zm-base-os:devcore-ubuntu-20.04 + resource_class: small + <<: *build_job_steps + + build_u18: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: zimbra/zm-base-os:devcore-ubuntu-18.04 + resource_class: small + <<: *build_job_steps + + build_c9: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: $DOCKER_REGISTRY/zm-base-os:devcore-centos-9 + auth: + username: $DOCKER_USER + password: $DOCKER_PASS + resource_class: small + <<: *build_job_steps + + build_c8: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: zimbra/zm-base-os:devcore-centos-8 + resource_class: small + <<: *build_job_steps + + build_c7: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + docker: + - image: zimbra/zm-base-os:devcore-centos-7 + resource_class: small + <<: *build_job_steps + + deploy_s3: + working_directory: ~/zm-onlyoffice + shell: /bin/bash -eo pipefail + <<: *deploy_s3_job_steps + +############################################################################ + +workflows: + version: 2 + main: + jobs: + - build: + type: approval + - checkout: + requires: + - build + - build_u22: + requires: + - checkout + context: + - docker-dev-registry + - build_u20: + requires: + - checkout + - build_u18: + requires: + - checkout + - build_c9: + requires: + - checkout + context: + - docker-dev-registry + - build_c8: + requires: + - checkout + - build_c7: + requires: + - checkout + - deploy_s3_hold: + type: approval + requires: + - build_u22 + - build_u20 + - build_u18 + - build_c9 + - build_c8 + - build_c7 + + - deploy_s3: + context: + - oracle + requires: + - deploy_s3_hold diff --git a/.gitignore b/.gitignore index b70f8847a..6ab919c2a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ node_modules /Gruntfile.js.out local-development-*.json *.pyc +.DS_Store diff --git a/Common/config/default.json b/Common/config/default.json index 2c1f01fec..89d59ae43 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -112,8 +112,12 @@ }, "services": { "CoAuthoring": { + "ssl" :{ + "key" : "", + "cert" : "" + }, "server": { - "port": 8000, + "port": 7084, "workerpercpu": 1, "mode": "development", "limits_tempfile_upload": 104857600, @@ -158,11 +162,11 @@ "limits_image_types_upload": "jpg;jpeg;jpe;png;gif;bmp" }, "sql": { - "type": "postgres", + "type": "mysql", "tableChanges": "doc_changes", "tableResult": "task_result", "dbHost": "localhost", - "dbPort": 5432, + "dbPort": 7306, "dbName": "onlyoffice", "dbUser": "onlyoffice", "dbPass": "onlyoffice", @@ -327,5 +331,21 @@ } ] } + }, + "FileStorage": { + "host": "", + "port": 4567, + "directory": "", + "silent": true + }, + "SpellChecker": { + "ssl" :{ + "key" : "", + "cert" : "" + }, + "server": { + "port": 7085, + "mode": "development" + } } -} +} \ No newline at end of file diff --git a/Common/config/log4js/logconfig.json b/Common/config/log4js/logconfig.json new file mode 100644 index 000000000..a6f117193 --- /dev/null +++ b/Common/config/log4js/logconfig.json @@ -0,0 +1,15 @@ +{ + "appenders": { + "default": { + "type": "file", + "filename": "/opt/zimbra/log/onlyoffice.log", + "layout": { + "type": "pattern", + "pattern": "[%d] [%p] %c - %.10000m" + } + } + }, + "categories": { + "default": { "appenders": [ "default" ], "level": "WARN" } + } +} \ No newline at end of file diff --git a/Common/config/onlyofficeconfig.json b/Common/config/onlyofficeconfig.json new file mode 100644 index 000000000..3f4cc7ecd --- /dev/null +++ b/Common/config/onlyofficeconfig.json @@ -0,0 +1,70 @@ +{ + "log": { + "filePath": "/opt/zimbra/onlyoffice/documentserver/server/Common/config/log4js/logconfig.json" + }, + "storage": { + "fs": { + "folderPath": "/opt/zimbra/onlyoffice/documentserver/App_Data/cache/files" + } + }, + "services": { + "CoAuthoring": { + "server": { + "static_content": { + "/fonts": { + "path": "/opt/zimbra/onlyoffice/documentserver/fonts", + "options": {"maxAge": "7d"} + }, + "/sdkjs": { + "path": "/opt/zimbra/onlyoffice/documentserver/sdkjs", + "options": {"maxAge": "7d"} + }, + "/web-apps": { + "path": "/opt/zimbra/onlyoffice/documentserver/web-apps", + "options": {"maxAge": "7d"} + }, + "/sdkjs-plugins": { + "path": "/opt/zimbra/onlyoffice/documentserver/sdkjs-plugins", + "options": {"maxAge": "7d"} + }, + "/App_Data": { + "path": "/opt/zimbra/onlyoffice/documentserver/App_Data", + "options": {"maxAge": "7d"} + } + } + }, + "utils": { + "utils_common_fontdir": "/usr/share/fonts" + }, + "request-filtering-agent" : { + "allowPrivateIPAddress": true, + "allowMetaIPAddress": true + }, + "sockjs": { + "sockjs_url": "/opt/zimbra/onlyoffice/documentserver/web-apps/vendor/sockjs/sockjs.min.js" + } + } + }, + "license": { + "license_file": "/opt/zimbra/onlyoffice/documentserver/license.lic", + "warning_limit_percents": 70, + "packageType": 0 + }, + "FileConverter": { + "converter": { + "fontDir": "/usr/share/fonts", + "presentationThemesDir": "/opt/zimbra/onlyoffice/documentserver/sdkjs/slide/themes", + "x2tPath": "/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin/x2t", + "docbuilderPath": "/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin/docbuilder", + "docbuilderAllFontsPath": "/opt/zimbra/onlyoffice/documentserver/App_Data/docbuilder/AllFonts.js" + } + }, + "FileStorage": { + "directory": "/opt/zimbra/onlyoffice/documentserver/App_Data" + }, + "SpellChecker": { + "server": { + "dictDir": "/opt/zimbra/onlyoffice/documentserver/dictionaries" + } + } +} \ No newline at end of file diff --git a/Common/sources/constants.js b/Common/sources/constants.js index 65d4c6f33..df96adbd2 100644 --- a/Common/sources/constants.js +++ b/Common/sources/constants.js @@ -83,7 +83,7 @@ exports.LICENSE_RESULT = { UsersViewCountOS: 15 }; -exports.LICENSE_CONNECTIONS = 20; +exports.LICENSE_CONNECTIONS = 99999; exports.LICENSE_EXPIRE_USERS_ONE_DAY = 24 * 60 * 60; // day in seconds exports.AVS_OFFICESTUDIO_FILE_UNKNOWN = 0x0000; diff --git a/DocService/sources/server.js b/DocService/sources/server.js index 5c744f642..68359f1b4 100644 --- a/DocService/sources/server.js +++ b/DocService/sources/server.js @@ -42,6 +42,7 @@ const fs = require('fs'); const express = require('express'); const http = require('http'); +const https = require('https'); const urlModule = require('url'); const path = require('path'); const bodyParser = require("body-parser"); @@ -59,7 +60,6 @@ const commonDefines = require('./../../Common/sources/commondefines'); const operationContext = require('./../../Common/sources/operationContext'); const tenantManager = require('./../../Common/sources/tenantManager'); const configStorage = configCommon.get('storage'); - const cfgWopiEnable = configCommon.get('wopi.enable'); const cfgHtmlTemplate = configCommon.get('wopi.htmlTemplate'); const cfgTokenEnableBrowser = configCommon.get('services.CoAuthoring.token.enable.browser'); @@ -68,11 +68,19 @@ const cfgTokenEnableRequestOutbox = configCommon.get('services.CoAuthoring.token const cfgLicenseFile = configCommon.get('license.license_file'); const app = express(); -app.disable('x-powered-by'); -//path.resolve uses __dirname by default(unexpected path in pkg) -app.set("views", path.resolve(process.cwd(), cfgHtmlTemplate)); -app.set("view engine", "ejs"); -const server = http.createServer(app); + +let server = null; + +if (config.has('ssl')) { + const privateKey = fs.readFileSync(config.get('ssl.key')).toString(); + const certificateKey = fs.readFileSync(config.get('ssl.cert')).toString(); + //See detailed options format here: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener + const options = {key: privateKey, cert: certificateKey}; + + server = https.createServer(options, app); +} else { + server = http.createServer(app); +} let licenseInfo, licenseOriginal, updatePluginsTime, userPlugins, pluginsLoaded; @@ -360,4 +368,4 @@ process.on('uncaughtException', (err) => { logger.shutdown(() => { process.exit(1); }); -}); +}); \ No newline at end of file diff --git a/Makefile.build b/Makefile.build new file mode 100644 index 000000000..f48c87af6 --- /dev/null +++ b/Makefile.build @@ -0,0 +1,55 @@ +######################################################################################################## + +SHELL = bash + +SHA512 = sha512sum + +OS = $(shell cat /etc/os-release | grep '^NAME' | cut -d'=' -f2 | cut -d'"' -f2) + +.PHONY: clean all + +######################################################################################################## + + +all: clean zimbra-onlyoffice-pkg + +######################################################################################################## + +ONLY_OFFICE_VERSION = 1.0 +ONLY_OFFICE_URL="https://files.zimbra.com/downloads/onlyoffice/u14/zimbra-onlyoffice-v7.2.2.56.tar.gz" + +stage-zimbra-onlyoffice-pkg: downloads + mkdir -p build/stage/zimbra-onlyoffice/opt/zimbra + cp -r downloads/onlyoffice build/stage/zimbra-onlyoffice/opt/zimbra/ + chmod +x build/stage/zimbra-onlyoffice/opt/zimbra/onlyoffice/bin/jq + cp -af bin/zmonlyofficeconfig build/stage/zimbra-onlyoffice/opt/zimbra/onlyoffice/bin/zmonlyofficeconfig + rm -rf build/stage/zimbra-onlyoffice/opt/zimbra/onlyoffice/.DS_Store + rm -rf build/stage/zimbra-onlyoffice/opt/zimbra/onlyoffice/._.DS_Store + +zimbra-onlyoffice-pkg: stage-zimbra-onlyoffice-pkg + ./pkg-build.pl \ + --pkg-version=$(ONLY_OFFICE_VERSION).$(shell git log --format=%at -1) \ + --pkg-release=1 \ + --pkg-name=zimbra-onlyoffice \ + --out-type=binary \ + --pkg-summary="Zimbra onlyoffice package" \ + --pkg-pre-install-script='scripts/preinst.sh' \ + --pkg-post-install-script='scripts/postinst.sh' \ + --pkg-installs='/opt/zimbra/onlyoffice/*' + + +downloads: + mkdir -p downloads + wget -O downloads/zimbra-onlyoffice.tar.gz $(ONLY_OFFICE_URL) + cd downloads/; tar -xf zimbra-onlyoffice.tar.gz + mv downloads/zimbra-onlyoffice downloads/onlyoffice + +######################################################################################################## + +######################################################################################################## + +clean: + rm -rf build + rm -rf downloads + +######################################################################################################## diff --git a/SpellChecker/sources/server.js b/SpellChecker/sources/server.js index 61bd8080e..756a45961 100644 --- a/SpellChecker/sources/server.js +++ b/SpellChecker/sources/server.js @@ -93,9 +93,9 @@ if (cluster.isMaster) { if (config.has('ssl')) { const privateKey = fs.readFileSync(config.get('ssl.key')).toString(); const certificateKey = fs.readFileSync(config.get('ssl.cert')).toString(); - const trustedCertificate = fs.readFileSync(config.get('ssl.ca')).toString(); + //See detailed options format here: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener - const options = {key: privateKey, cert: certificateKey, ca: [trustedCertificate]}; + const options = {key: privateKey, cert: certificateKey}; server = https.createServer(options, app); } else { diff --git a/bin/createdb.sql b/bin/createdb.sql new file mode 100644 index 000000000..68de88c20 --- /dev/null +++ b/bin/createdb.sql @@ -0,0 +1,81 @@ +-- +-- Create schema onlyoffice +-- +CREATE DATABASE IF NOT EXISTS onlyoffice DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; +--CREATE USER IF NOT EXISTS 'onlyoffice' IDENTIFIED BY 'onlyoffice'; +--grant all on onlyoffice.* to 'onlyoffice' identified by 'onlyoffice'; +GRANT ALL PRIVILEGES ON onlyoffice.* TO 'zimbra'; +FLUSH PRIVILEGES; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + + +USE onlyoffice; + +-- +-- Definition of table `doc_changes` +-- + +CREATE TABLE IF NOT EXISTS `doc_changes` ( + `tenant` varchar(255) NOT NULL, + `id` varchar(255) NOT NULL, + `change_id` int(10) unsigned NOT NULL, + `user_id` varchar(255) NOT NULL, + `user_id_original` varchar(255) NOT NULL, + `user_name` varchar(255) NOT NULL, + `change_data` longtext NOT NULL, + `change_date` datetime NOT NULL, + PRIMARY KEY (`tenant`, `id`,`change_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `doc_changes` +-- + +/*!40000 ALTER TABLE `doc_changes` DISABLE KEYS */; +/*!40000 ALTER TABLE `doc_changes` ENABLE KEYS */; + +-- +-- Definition of table `task_result` +-- + +CREATE TABLE IF NOT EXISTS `task_result` ( + `tenant` varchar(255) NOT NULL, + `id` varchar(255) NOT NULL, + `status` tinyint(3) NOT NULL, + `status_info` int(10) NOT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `last_open_date` datetime NOT NULL, + `user_index` int(10) unsigned NOT NULL DEFAULT 1, + `change_id` int(10) unsigned NOT NULL DEFAULT 0, + `callback` longtext NOT NULL, + `baseurl` text NOT NULL, + `password` longtext NULL, + `additional` longtext NULL, + PRIMARY KEY (`tenant`, `id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `task_result` +-- + +/*!40000 ALTER TABLE `task_result` DISABLE KEYS */; +/*!40000 ALTER TABLE `task_result` ENABLE KEYS */; + + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/bin/jq b/bin/jq new file mode 100644 index 000000000..f48b0ca92 Binary files /dev/null and b/bin/jq differ diff --git a/bin/process_id.json b/bin/process_id.json new file mode 100644 index 000000000..9bdeba80c --- /dev/null +++ b/bin/process_id.json @@ -0,0 +1,4 @@ +{ + "docservice": -1, + "converter" : -1 +} diff --git a/bin/zmonlyofficeconfig b/bin/zmonlyofficeconfig new file mode 100644 index 000000000..510bc6e54 --- /dev/null +++ b/bin/zmonlyofficeconfig @@ -0,0 +1,260 @@ +#!/bin/bash +# +# ***** BEGIN LICENSE BLOCK ***** +# Zimbra Collaboration Suite Server +# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2021 Synacor, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software Foundation, +# version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with this program. +# If not, see . +# ***** END LICENSE BLOCK ***** +# + +source /opt/zimbra/bin/zmshutil || exit 1 +zmsetvars + +zmjq="/opt/zimbra/onlyoffice/bin/jq" + +defaultjson_path="/opt/zimbra/onlyoffice/documentserver/server/Common/config/default.json" +mysql_port=7306 +zimbra_mysql_user="zimbra" +zimbra_mysql_password="" + +# Check for commercial certificates +if [ -f /opt/zimbra/ssl/zimbra/commercial/commercial.crt ] && [ -f /opt/zimbra/ssl/zimbra/commercial/commercial.key ]; then + server_crt="/opt/zimbra/ssl/zimbra/commercial/commercial.crt" + server_key="/opt/zimbra/ssl/zimbra/commercial/commercial.key" +else + server_crt="/opt/zimbra/ssl/zimbra/server/server.crt" + server_key="/opt/zimbra/ssl/zimbra/server/server.key" +fi + +STATUS=0 + +document_editing_JWT_secret="" + +usage() { + echo "" + echo "Invalid argument. Allowed :" + echo "new Configure Onlyoffice on the server" + echo "update-jwt-secret arg0 Update Onlyoffice server's jwt secret with the passed value" + echo "update-db Update Onlyoffice server's DB connection details from config" + echo "update-certificate Update Onlyoffice server's certificate paths" + echo "" + exit +} + +generate_random() +{ + length=8 + digits=({2..9}) + lower=({a..k} {m..n} {p..z}) + upper=({A..N} {P..Z}) + CharArray=(${digits[*]} ${lower[*]} ${upper[*]}) + ArrayLength=${#CharArray[*]} + password="" + while [ $length -gt 0 ] + do + index=$(($RANDOM%$ArrayLength)) + char=${CharArray[$index]} + password=${password}${char} + ((length--)) + done + echo "$password" +} + +update_db_config() +{ + #port + config_mysql_port=$(su - zimbra -c "zmlocalconfig -x -s mysql_port") + if [ -n "$config_mysql_port" ]; then + IFS='=' + read -ra arr <<< "$config_mysql_port" + mysql_port=$(echo "${arr[1]}" | xargs) + fi + + content=$(${zmjq} --argjson mysql_port "$mysql_port" '.services.CoAuthoring.sql.dbPort=$mysql_port' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + #user + config_mysql_user=$(su - zimbra -c "zmlocalconfig -x -s zimbra_mysql_user") + if [ -n "$config_mysql_user" ]; then + IFS='=' + read -ra arr <<< "$config_mysql_user" + zimbra_mysql_user=$(echo "${arr[1]}" | xargs) + fi + + content=$(${zmjq} --arg zimbra_mysql_user "$zimbra_mysql_user" '.services.CoAuthoring.sql.dbUser=$zimbra_mysql_user' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + #password + config_mysql_pass=$(su - zimbra -c "zmlocalconfig -x -s zimbra_mysql_password") + if [ -n "$config_mysql_pass" ]; then + IFS='=' + read -ra arr <<< "$config_mysql_pass" + zimbra_mysql_password=$(echo "${arr[1]}" | xargs) + fi + + content=$(${zmjq} --arg zimbra_mysql_password "$zimbra_mysql_password" '.services.CoAuthoring.sql.dbPass=$zimbra_mysql_password' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + +} + +update_certificate_path() +{ + content=$(${zmjq} --arg server_crt "$server_crt" '.services.CoAuthoring.ssl.cert=$server_crt' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} --arg server_crt "$server_crt" '.SpellChecker.ssl.cert=$server_crt' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} --arg server_key "$server_key" '.services.CoAuthoring.ssl.key=$server_key' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} --arg server_key "$server_key" '.SpellChecker.ssl.key=$server_key' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} +} + +update_token_config() +{ + + content=$(${zmjq} '.services.CoAuthoring.token.enable.browser=true' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} '.services.CoAuthoring.token.enable.request.inbox=true' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} '.services.CoAuthoring.token.enable.request.outbox=true' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} '.services.CoAuthoring.requestDefaults.rejectUnauthorized=false' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + +} + +update_jwt_config() +{ + jwtsecret=$1 + cmd="su - zimbra -c \"zmprov -m -l mcf zimbraDocumentEditingJwtSecret ${jwtsecret}\"" + eval "$cmd" + RC=$? + if [ $RC -ne "0" ]; then + STATUS=$R + echo "Updating zimbraDocumentEditingJwtSecret faced problem." + fi + + #update the default.json + content=$(${zmjq} --arg jwtsecret "$jwtsecret" '.services.CoAuthoring.secret.browser.string=$jwtsecret' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} --arg jwtsecret "$jwtsecret" '.services.CoAuthoring.secret.inbox.string=$jwtsecret' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} --arg jwtsecret "$jwtsecret" '.services.CoAuthoring.secret.outbox.string=$jwtsecret' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} + + content=$(${zmjq} --arg jwtsecret "$jwtsecret" '.services.CoAuthoring.secret.session.string=$jwtsecret' ${defaultjson_path}) + echo "${content}" > ${defaultjson_path} +} + +set_jwt_secret() +{ + echo "Setting Random Secret..." + jwtsecret=$(generate_random) + update_jwt_config "$jwtsecret" +} + +generate_fonts_data() +{ + mkdir -p /opt/zimbra/onlyoffice/documentserver/fonts + + fonts_gen=$(LD_LIBRARY_PATH=/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin /opt/zimbra/onlyoffice/documentserver/server/tools/allfontsgen \ + --input="/opt/zimbra/onlyoffice/documentserver/core-fonts" \ + --allfonts-web="/opt/zimbra/onlyoffice/documentserver/sdkjs/common/AllFonts.js" \ + --allfonts="/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin/AllFonts.js" \ + --images="/opt/zimbra/onlyoffice/documentserver/sdkjs/common/Images" \ + --selection="/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin/font_selection.bin" \ + --output-web="/opt/zimbra/onlyoffice/documentserver/fonts" \ + --use-system="true") + R=$? + if [ $R -ne "0" ]; then + STATUS=$R + echo "Error while generating fonts. ${fonts_gen}" + fi + +} + +generate_presentation_themes() +{ + presentation_themes_gen=$(LD_LIBRARY_PATH=/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin /opt/zimbra/onlyoffice/documentserver/server/tools/allthemesgen \ + --converter-dir="/opt/zimbra/onlyoffice/documentserver/server/FileConverter/bin"\ + --src="/opt/zimbra/onlyoffice/documentserver/sdkjs/slide/themes"\ + --output="/opt/zimbra/onlyoffice/documentserver/sdkjs/common/Images") + R=$? + if [ $R -ne "0" ]; then + STATUS=$R + echo "Error while generating presentation themes. ${presentation_themes_gen}" + fi +} + +type="$1" +if [ "$#" -eq 0 ]; then + type="new" +fi + + +case "$type" in + new) + + jwtsecret=$(su - zimbra -c "zmprov -m -l getConfig zimbraDocumentEditingJwtSecret") + if [ -z "$jwtsecret" ]; then + echo "JWT Secret not set." + set_jwt_secret + else + IFS=':' + read -ra arr <<< "$jwtsecret" + document_editing_JWT_secret=$(echo "${arr[1]}" | xargs) + update_jwt_config "$document_editing_JWT_secret" + fi + + update_certificate_path + update_token_config + update_db_config + generate_fonts_data + generate_presentation_themes + echo "Onlyoffice configuration done." + exit $STATUS + ;; + + update-jwt-secret) + + if [ "$#" -ne 2 ]; then + usage + exit 1 + fi + jwtsecret="$2" + + update_jwt_config "$jwtsecret" + exit $STATUS + ;; + + update-db ) + update_db_config + exit $STATUS + ;; + + update-certificate ) + update_certificate_path + exit $STATUS + ;; + + *) + usage + exit 1 + ;; +esac diff --git a/pkg-build.pl b/pkg-build.pl new file mode 100755 index 000000000..c1bb67ac8 --- /dev/null +++ b/pkg-build.pl @@ -0,0 +1,714 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Config; +use Cwd; +use Data::Dumper; +use File::Basename; +use File::Copy; +use File::Find; +use File::Path qw/make_path/; +use Getopt::Long; +use IPC::Cmd qw/run can_run/; +use Term::ANSIColor; + +my $GLOBAL_PATH_TO_SCRIPT_FILE; +my $GLOBAL_PATH_TO_SCRIPT_DIR; +my $GLOBAL_PATH_TO_TOP; +my $CWD; +my $ZM_PKG_TOOL_DIR; +my $PKG_CREATION_DATE = `date -R`; + +my %CFG = (); + +BEGIN +{ + $ENV{ANSI_COLORS_DISABLED} = 1 if ( ! -t STDOUT ); + $GLOBAL_PATH_TO_SCRIPT_FILE = Cwd::abs_path(__FILE__); + $GLOBAL_PATH_TO_SCRIPT_DIR = dirname($GLOBAL_PATH_TO_SCRIPT_FILE); + $GLOBAL_PATH_TO_TOP = dirname($GLOBAL_PATH_TO_SCRIPT_DIR); + $ZM_PKG_TOOL_DIR = $GLOBAL_PATH_TO_TOP."/zm-pkg-tool"; + $GLOBAL_PATH_TO_SCRIPT_DIR = $ZM_PKG_TOOL_DIR; + $CWD = getcwd(); +} + +sub LoadConfiguration($) +{ + my $args = shift; + + my $cfg_name = $args->{name}; + my $cmd_hash = $args->{hash_src}; + my $default_sub = $args->{default_sub}; + my $validate_sub = $args->{validate_sub}; + + my $val; + my $src; + + if ( !defined $val ) + { + y/A-Z_/a-z-/ foreach ( my $cmd_name = $cfg_name ); + + if ( $cmd_hash && exists $cmd_hash->{$cmd_name} ) + { + $val = $cmd_hash->{$cmd_name}; + $src = "cmdline"; + } + } + + if ( !defined $val ) + { + if ( $CFG{CFG_DIR} ) + { + my $file = "$CFG{CFG_DIR}/config.pl"; + my $hash = LoadProperties($file) + if ( -f $file ); + + if ( $hash && exists $hash->{$cfg_name} ) + { + $val = $hash->{$cfg_name}; + $src = "config" + } + } + } + + my $valid = 1; + + if ( defined $val ) + { + $valid = &$validate_sub($val) + if ($validate_sub); + } + + if ( !defined $val || !$valid ) + { + if ($default_sub) + { + $val = &$default_sub($cfg_name); + $src = "default" . ( $valid ? "" : "($src was rejected)" ); + } + } + + if ( defined $val ) + { + $valid = &$validate_sub($val) + if ($validate_sub); + + if ( ref($val) eq "HASH" ) + { + foreach my $k ( keys %{$val} ) + { + $CFG{$cfg_name}{$k} = ${$val}{$k}; + + printf( " %-25s: %-17s : %s\n", $cfg_name, $cmd_hash ? $src : "detected", "{" . $k . " => " . ${$val}{$k} . "}" ); + } + } + elsif ( ref($val) eq "ARRAY" ) + { + $CFG{$cfg_name} = $val; + + printf( " %-25s: %-17s : %s\n", $cfg_name, $cmd_hash ? $src : "detected", "[" . join( ", ", @{ $CFG{$cfg_name} } ) . "]" ); + } + else + { + $CFG{$cfg_name} = $val; + + printf( " %-25s: %-17s : %s\n", $cfg_name, $cmd_hash ? $src : "detected", $val ); + } + } +} + + +sub Die($;$) +{ + my $msg = shift; + my $info = shift || ""; + my $err = "$!"; + + print "\n"; + print "\n"; + print "=========================================================================================================\n"; + print color('red') . "FAILURE MSG" . color('reset') . " : $msg\n"; + print color('red') . "SYSTEM ERR " . color('reset') . " : $err\n" if ($err); + print color('red') . "EXTRA INFO " . color('reset') . " : $info\n" if ($info); + print "\n"; + print "=========================================================================================================\n"; + print color('red'); + print "--Stack Trace--\n"; + my $i = 1; + + while ( ( my @call_details = ( caller( $i++ ) ) ) ) + { + print $call_details[1] . ":" . $call_details[2] . " called from " . $call_details[3] . "\n"; + } + print color('reset'); + print "\n"; + print "=========================================================================================================\n"; + + die "END"; +} + + +sub assert($$;$) +{ + my $l = shift || ""; + my $r = shift || ""; + my $m = shift || ""; + + Die( $m, "Got:[$l] != Exp:[$r]" ) + if ( $l ne $r ); +} + +sub LoadProperties($) +{ + my $f = shift; + + my $x = SlurpFile($f); + + my @cfg_kvs = + map { $_ =~ s/^\s+|\s+$//g; $_ } # trim + map { split( /=/, $_, 2 ) } # split around = + map { $_ =~ s/#.*$//g; $_ } # strip comments + grep { $_ !~ /^\s*#/ } # ignore comments + grep { $_ !~ /^\s*$/ } # ignore empty lines + @$x; + + my %ret_hash = (); + for ( my $e = 0 ; $e < scalar @cfg_kvs ; $e += 2 ) + { + my $probe_key = $cfg_kvs[$e]; + my $probe_val = $cfg_kvs[ $e + 1 ]; + + if ( $probe_key =~ /^%(.*)/ ) + { + my @val_kv_pair = split( /=/, $probe_val, 2 ); + + $ret_hash{$1}{ $val_kv_pair[0] } = $val_kv_pair[1]; + } + else + { + $ret_hash{$probe_key} = $probe_val; + } + } + + return \%ret_hash; +} + + +sub SlurpFile($) +{ + my $f = shift; + + open( FD, "<", "$f" ) || Die( "In open for read", "file='$f'" ); + + chomp( my @x = ); + close(FD); + + return \@x; +} + +sub System(@) +{ + my $cmd_str = "@_"; + + print color('green') . "#: pwd=@{[Cwd::getcwd()]}" . color('reset') . "\n"; + print color('green') . "#: $cmd_str" . color('reset') . "\n"; + + $! = 0; + my ( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ) = run( command => \@_, verbose => 1 ); + + Die( "cmd='$cmd_str'", $error_message ) + if ( !$success ); + + return { msg => $error_message, out => $stdout_buf, err => $stderr_buf }; +} + +sub GetPkgFormat() +{ + if ( -f "/etc/redhat-release" ) + { + return "rpm"; + } + elsif ( -f "/etc/lsb-release" ) + { + return "deb"; + } + else + { + Die("Unknown OS"); + } +} + +sub GetOsTag() +{ + our $gOSTAG; + + if ( !defined $gOSTAG ) + { + if ( -f "/etc/redhat-release" ) + { + chomp( $gOSTAG = `sed -n -e '1{s/[^0-9]*/r/; s/[.].*//; p;}' /etc/redhat-release` ); + } + elsif ( -f "/etc/lsb-release" ) + { + chomp( $gOSTAG = `sed -n -e '/DISTRIB_RELEASE/{s/.*=/u/; s/[.].*//; p;}' /etc/lsb-release` ); + } + else + { + Die("Unknown OS"); + } + } + + return $gOSTAG +} + +sub _ValidateOutType($) +{ + my $ty = shift; + + if ( defined $ty ) + { + return 1 if ( $ty eq "all" ); + return 1 if ( $ty eq "source" ); + return 1 if ( $ty eq "binary" ); + } + + return undef; +} + +sub Init() +{ + my %cmd_hash = (); + + my @cmd_args = ( + { + name => "CFG_DIR", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return "pkg-spec"; }, + }, + { + name => "OUT_TYPE", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => &_ValidateOutType, + default_sub => sub { return "all"; }, + }, + { + name => "OUT_BASE_DIR", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return "build"; }, + }, + { + name => "OUT_TEMP_DIR", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return "$CFG{OUT_BASE_DIR}/tmp"; }, + }, + { + name => "OUT_STAGE_DIR", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return "$CFG{OUT_BASE_DIR}/stage"; }, + }, + { + name => "OUT_DIST_DIR", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return "$CFG{OUT_BASE_DIR}/dist"; }, + }, + { + name => "PKG_NAME", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return Die("@_ not unspecfied"); }, + }, + { + name => "PKG_RELEASE", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return Die("@_ not specified"); }, + }, + { + name => "PKG_VERSION", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return Die("@_ not specified"); }, + }, + { + name => "PKG_SUMMARY", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return Die("@_ not specified"); }, + }, + { + name => "PKG_INSTALLS", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_DEPENDS", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_PRE_DEPENDS", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_PROVIDES", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_CONFLICTS", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_OBSOLETES", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_REPLACES", + type => "=s@", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return []; }, + }, + { + name => "PKG_PRE_INSTALL_SCRIPT", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return undef; }, + }, + { + name => "PKG_POST_INSTALL_SCRIPT", + type => "=s", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return undef; }, + }, + { + name => "PKG_FORMAT", + type => "", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return GetPkgFormat(); }, + }, + { + name => "PKG_OS_TAG", + type => "", + hash_src => \%cmd_hash, + validate_sub => undef, + default_sub => sub { return GetOsTag(); }, + }, + ); + + { + my @cmd_opts = + map { $_->{opt} =~ y/A-Z_/a-z-/; $_; } # convert the opt named to lowercase to make command line options + map { { opt => $_->{name}, opt_s => $_->{type} } } # create a new hash with keys opt, opt_s + grep { $_->{type} } # get only names which have a valid type + @cmd_args; + + my $help_func = sub { + print "Usage: $0 \n"; + print "Supported options: \n"; + print " --" . "$_->{opt}$_->{opt_s}\n" foreach (@cmd_opts); + exit(0); + }; + + if ( !GetOptions( \%cmd_hash, ( map { $_->{opt} . $_->{opt_s} } @cmd_opts ), help => $help_func ) ) + { + print Die("wrong commandline options, use --help"); + } + } + + print "=========================================================================================================\n"; + LoadConfiguration($_) foreach (@cmd_args); + print "=========================================================================================================\n"; +} + + +sub _SanitizePkgList($) +{ + my $list = shift; + + my $san_list = ""; + foreach my $entry ( @{$list} ) + { + $entry =~ s/\s//g; + $entry =~ s/\/|/g; + $entry =~ s/[|][|]*/|/g; + + my @comp = split( /[|]/, $entry ); + + my $san_entry = ""; + foreach my $comp_entry (@comp) + { + # abc-2.5 -> $pkn + # abc-2.5>=2.1.0-1 -> $pkn$cmp$ver + # abc-2.5(>=2.1.0-1) -> $pkn($cmp$ver) + if ( $comp_entry =~ m/^([^>=<]+)([>=<]*)(.*)$/ ) + { + my $pkn = $1; + my $cmp = $2; + my $ver = $3; + + $pkn =~ s/[(]$//; + $ver =~ s/[)]$//; + + my $no_add_os_tag = 1 + if ( $ver =~ s/[!]$// ); + + my $san_comp = ""; + + if ($pkn) + { + $san_comp = $pkn; + + if ( $cmp && $ver ) + { + my $tag = ( !$no_add_os_tag && $ver =~ m/[-][^-]*$/ ) ? ".$CFG{PKG_OS_TAG}" : ""; + + if ( $CFG{PKG_FORMAT} eq "deb" ) + { + $cmp = ">>" if ( $cmp eq ">" ); + $cmp = "<<" if ( $cmp eq "<" ); + $cmp = "=" if ( $cmp eq "==" ); + + $san_comp .= " (" . $cmp . " " . $ver . "$tag)"; + } + if ( $CFG{PKG_FORMAT} eq "rpm" ) + { + $cmp = ">" if ( $cmp eq ">>" ); + $cmp = "<" if ( $cmp eq "<<" ); + $cmp = "=" if ( $cmp eq "==" ); + + $san_comp .= " " . $cmp . " " . $ver . "$tag"; + } + } + } + + $san_entry .= ( $san_entry && $san_comp ? " | " : "" ) . $san_comp + if ( $CFG{PKG_FORMAT} eq "deb" ); + $san_entry .= ( $san_entry && $san_comp ? " or " : "" ) . $san_comp + if ( $CFG{PKG_FORMAT} eq "rpm" ); + } + } + + $san_list .= ( $san_list && $san_entry ? ", " : "" ) . $san_entry; + } + + return $san_list; +} + + +sub Build() +{ + System( "rm", "-f", $_ ) foreach glob("$CFG{OUT_DIST_DIR}/$CFG{PKG_OS_TAG}/$CFG{PKG_NAME}_*"); + System( "rm", "-f", $_ ) foreach glob("$CFG{OUT_DIST_DIR}/$CFG{PKG_OS_TAG}/$CFG{PKG_NAME}-*.rpm"); + + System( "rm", "-rf", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/" ); + System( "mkdir", "-p", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/" ); + System( "mkdir", "-p", "$CFG{OUT_DIST_DIR}/$CFG{PKG_OS_TAG}/" ); + + my $pkg_pre_install_list = ""; + my $pkg_post_install_list = ""; + if ( defined $CFG{PKG_POST_INSTALL_SCRIPT}) { + open FILE, "$CFG{PKG_POST_INSTALL_SCRIPT}" or die "Couldn't open postinst file: $!"; + $pkg_post_install_list = join("", ); + close FILE; + } + if ( defined $CFG{PKG_PRE_INSTALL_SCRIPT}) { + open FILE, "$CFG{PKG_PRE_INSTALL_SCRIPT}" or die "Couldn't open preinst file: $!"; + $pkg_pre_install_list = join("", ); + close FILE; + } + + if ( $CFG{PKG_FORMAT} eq "rpm" ) + { + System( "cp", "-a", "$GLOBAL_PATH_TO_SCRIPT_DIR/default-template/rpm", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/" ); + System( "cp", "-a", "$CFG{CFG_DIR}/rpm", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/SPECS" ) if ( -d "$CFG{CFG_DIR}/rpm" ); + } + elsif ( $CFG{PKG_FORMAT} eq "deb" ) + { + System( "cp", "-a", "$GLOBAL_PATH_TO_SCRIPT_DIR/default-template/debian", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/" ); + System( "cp", "-a", "$CFG{CFG_DIR}/debian", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/" ) if ( -d "$CFG{CFG_DIR}/debian" ); + } + else + { + Die("Unknown PACKAGING format"); + } + + find( + { + wanted => sub { + my $tpl_file = $_; + if ( -f $tpl_file && $tpl_file =~ /[.]in$/ ) + { + s/[.]in$// for ( my $new_file = $tpl_file ); + + open( FDr, "<", "$tpl_file" ); + open( FDw, ">", "$new_file" ); + + while ( my $line = ) + { + { + my $pkg_install_list = + ( $CFG{PKG_FORMAT} eq "deb" && $tpl_file =~ /install[.]in/ ) + ? join( "\n", map { $_ =~ s,^/,,; $_ } @{ $CFG{PKG_INSTALLS} } ) + : join( "\n", @{ $CFG{PKG_INSTALLS} } ); + + $line =~ s/[@][@]PKG_INSTALLS[@][@]/$pkg_install_list/g; + } + $line =~ s/[@][@]PKG_POST_INSTALL[@][@]/$pkg_post_install_list/g; + $line =~ s/[@][@]PKG_PRE_INSTALL[@][@]/$pkg_pre_install_list/g; + $line =~ s/[@][@]PKG_NAME[@][@]/$CFG{PKG_NAME}/g; + $line =~ s/[@][@]PKG_RELEASE[@][@]/$CFG{PKG_RELEASE}/g; + $line =~ s/[@][@]PKG_OS_TAG[@][@]/$CFG{PKG_OS_TAG}/g; + $line =~ s/[@][@]PKG_VERSION[@][@]/$CFG{PKG_VERSION}/g; + $line =~ s/[@][@]PKG_SUMMARY[@][@]/$CFG{PKG_SUMMARY}/g; + $line =~ s/[@][@]PKG_CREATION_DATE[@][@]/$PKG_CREATION_DATE/g; + $line =~ s/[@][@]PKG_DEPENDS[@][@]/@{[_SanitizePkgList($CFG{PKG_DEPENDS})]}/g; + $line =~ s/[@][@]PKG_PRE_DEPENDS[@][@]/@{[_SanitizePkgList($CFG{PKG_PRE_DEPENDS})]}/g; + $line =~ s/[@][@]PKG_PROVIDES[@][@]/@{[_SanitizePkgList($CFG{PKG_PROVIDES})]}/g; + $line =~ s/[@][@]PKG_CONFLICTS[@][@]/@{[_SanitizePkgList($CFG{PKG_CONFLICTS})]}/g; + $line =~ s/[@][@]PKG_OBSOLETES[@][@]/@{[_SanitizePkgList($CFG{PKG_OBSOLETES})]}/g; + $line =~ s/[@][@]PKG_REPLACES[@][@]/@{[_SanitizePkgList($CFG{PKG_REPLACES})]}/g; + + if ( $line =~ m/^\s*[A-Za-z][A-Za-z_0-9-]*\s*[:](\s*,*\s*)*$/ ) # drop lines with empty headers + { + } + else + { + print FDw $line; + } + } + + close(FDr); + close(FDw); + + unlink($tpl_file); + } + }, + }, + "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}" + ); + + System( "make", "-f", "$CFG{CFG_DIR}/$CFG{PKG_NAME}/Makefile", "PKG_NAME=$CFG{PKG_NAME}", "PKG_STAGE_DIR=$CFG{OUT_STAGE_DIR}/$CFG{PKG_NAME}", "stage" ) + if ( -f "$CFG{CFG_DIR}/$CFG{PKG_NAME}/Makefile" ); + + System( "ant", "-f", "$CFG{CFG_DIR}/$CFG{PKG_NAME}/build.xml", "-DPKG_NAME=$CFG{PKG_NAME}", "-DPKG_STAGE_DIR=$CFG{OUT_STAGE_DIR}/$CFG{PKG_NAME}", "stage" ) + if ( -f "$CFG{CFG_DIR}/$CFG{PKG_NAME}/build.xml" ); + + if ( $CFG{PKG_FORMAT} eq "rpm" ) + { + my @pkg_type_opts = ("-ba"); + @pkg_type_opts = ("-bb") if ( $CFG{OUT_TYPE} eq "binary" ); + @pkg_type_opts = ("-bs") if ( $CFG{OUT_TYPE} eq "source" ); + + System( "mv", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/rpm/1.spec", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/rpm/$CFG{PKG_NAME}.spec" ); + System( "mkdir", "-p", "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/BUILDROOT/" ); + + System( "cp", "-a", $_, "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/BUILDROOT/@{[basename $_]}" ) foreach glob("$CFG{OUT_STAGE_DIR}/$CFG{PKG_NAME}/*"); + + { + System( "rpmbuild", "-v", "--define", "_topdir $CWD/$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}", "--buildroot=$CWD/$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/BUILDROOT/", @pkg_type_opts, "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/rpm/$CFG{PKG_NAME}.spec" ); + } + + print "\n\n"; + print "=========================================================================================================\n"; + System( "mv", "-v", $_, "$CFG{OUT_DIST_DIR}/$CFG{PKG_OS_TAG}/" ) foreach glob("$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/SRPMS/*.rpm"); + System( "mv", "-v", $_, "$CFG{OUT_DIST_DIR}/$CFG{PKG_OS_TAG}/" ) foreach glob("$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/RPMS/*/*.rpm"); + print "=========================================================================================================\n"; + } + elsif ( $CFG{PKG_FORMAT} eq "deb" ) + { + my @pkg_type_opts = ( "-uc", "-us" ); + push( @pkg_type_opts, "-b" ) if ( $CFG{OUT_TYPE} eq "binary" ); + push( @pkg_type_opts, "-S" ) if ( $CFG{OUT_TYPE} eq "source" ); + open(my $fd, ">>$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/debian/rules"); + print $fd "override_dh_strip: \n"; + print $fd " cp -r \$\$(pwd)/opt/zimbra/onlyoffice/documentserver/server/DocService/docservice \$\$(pwd)/debian/zimbra-onlyoffice/opt/zimbra/onlyoffice/documentserver/server/DocService/docservice \n"; + print $fd "override_dh_strip_nondeterminism: \n"; + print $fd "override_dh_shlibdeps: \n"; + print $fd "override_dh_builddeb:\n"; + print $fd " dh_builddeb -- -Zgzip\n"; + close($fd); + + System( "cp", "-a", $_, "$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}/@{[basename $_]}" ) foreach glob("$CFG{OUT_STAGE_DIR}/$CFG{PKG_NAME}/*"); + + { + chdir("$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}"); + print "$CWD \n"; + System( "dpkg-buildpackage", @pkg_type_opts ); + chdir($CWD); + } + + print "\n\n"; + print "=========================================================================================================\n"; + System( "mv", "-v", $_, "$CFG{OUT_DIST_DIR}/$CFG{PKG_OS_TAG}/" ) foreach glob("$CFG{OUT_TEMP_DIR}/$CFG{PKG_NAME}_*.*"); + print "=========================================================================================================\n"; + } + else + { + Die("Unknown PACKAGING format"); + } +} + +sub SelfTest() +{ + if ( $CFG{PKG_FORMAT} eq "DEB" ) + { + assert( + _SanitizePkgList( [ "abc-3.4(>=4.4)", "def-6.7(>6.6-1)", "def-6.7(>6.6-1!)", "ghi(=7.0)", "jkl", "aaa | bbb | perl(Carp) >= 3.2" ] ), + "abc-3.4 (>= 4.4), def-6.7 (>> 6.6-1.$CFG{PKG_OS_TAG}), def-6.7 (>> 6.6-1), ghi (= 7.0), jkl, aaa | bbb | perl(Carp) (>= 3.2)" + ); + } + + if ( $CFG{PKG_FORMAT} eq "RPM" ) + { + assert( + _SanitizePkgList( [ "abc-3.4(>=4.4)", "def-6.7(>6.6-1)", "def-6.7(>6.6-1!)", "ghi(=7.0)", "jkl", "aaa | bbb | perl(Carp) >= 3.2" ] ), + "abc-3.4 >= 4.4, def-6.7 > 6.6-1.$CFG{PKG_OS_TAG}, def-6.7 > 6.6-1, ghi = 7.0, jkl, aaa or bbb or perl(Carp) >= 3.2" + ); + } +} + + +sub main() +{ + Init(); + SelfTest(); + Build(); +} + +main(); diff --git a/scripts/postinst.sh b/scripts/postinst.sh new file mode 100755 index 000000000..053b0f07f --- /dev/null +++ b/scripts/postinst.sh @@ -0,0 +1,21 @@ +if [ -f /opt/zimbra/onlyoffice/bin/jq ]; then + chmod +x /opt/zimbra/onlyoffice/bin/jq +fi + +if [ -f /opt/zimbra/onlyoffice/bin/zmonlyofficeconfig ]; then + chmod +x /opt/zimbra/onlyoffice/bin/zmonlyofficeconfig +fi + +if [ -f /opt/zimbra/onlyoffice/bin/process_id.json.bak ]; then + mv -f /opt/zimbra/onlyoffice/bin/process_id.json.bak /opt/zimbra/onlyoffice/bin/process_id.json + /opt/zimbra/onlyoffice/bin/zmonlyofficeconfig +fi + +if [ -f /opt/zimbra/onlyoffice/bin/process_id.json ]; then + chmod 775 /opt/zimbra/onlyoffice/bin/process_id.json + chown zimbra:zimbra /opt/zimbra/onlyoffice/bin/process_id.json +fi + +if [ -d /opt/zimbra/onlyoffice ]; then + chown -R zimbra:zimbra /opt/zimbra/onlyoffice/ +fi diff --git a/scripts/preinst.sh b/scripts/preinst.sh new file mode 100755 index 000000000..8d5fcb257 --- /dev/null +++ b/scripts/preinst.sh @@ -0,0 +1,5 @@ +if [ -f /opt/zimbra/onlyoffice/bin/process_id.json ]; then + cp -af /opt/zimbra/onlyoffice/bin/process_id.json /opt/zimbra/onlyoffice/bin/process_id.json.bak + chmod 775 /opt/zimbra/onlyoffice/bin/process_id.json.bak + chown zimbra:zimbra /opt/zimbra/onlyoffice/bin/process_id.json.bak +fi