How to Migrate LibreOffice to Function Compute

$ soffice --convert-to pdf --outdir /tmp /tmp/test.doc
  • Recompile and tailor LibreOffice to adapt it to the built-in gcc and kernel versions of the FC nodejn8 runtime environment.
  • Install libssl3 dependencies that were missing during the runtime.
  • Download and extract it during OSS runtime to override the 50 MB limit for ZIP packages.
  • The example project has been created to support one-click deployment for a quick experience.

Preparation

brew tap vangie/formula
brew install fun
npm install @alicloud/fun -g

Compile LibreOffice

Start a Compilation Environment

docker run --name libre-builder --rm  -v $(pwd):/code -d -t --cap-add=SYS_PTRACE --security-opt seccomp=unconfined aliyunfc/runtime-nodejs8:build bash

Install the Compilation Tool

apt-get install -y ccache
apt-get build-dep -y libreoffice

Clone the Source Code

git clone --depth=1 git://anongit.freedesktop.org/libreoffice/core libreoffice
cd libreoffice

Configure and Compile

# For compilation of the software program multiple times, this setting can accelerate the progress of subsequent compilations.
ccache --max-size 16 G && ccache -s
# The most important part. Run ./autogen.sh --help to see what each option means
./autogen.sh --disable-report-builder --disable-lpsolve --disable-coinmp \
--enable-mergelibs --disable-odk --disable-gtk --disable-cairo-canvas \
--disable-dbus --disable-sdremote --disable-sdremote-bluetooth --disable-gio --disable-randr \
--disable-gstreamer-1-0 --disable-cve-tests --disable-cups --disable-extension-update \
--disable-postgresql-sdbc --disable-lotuswordpro --disable-firebird-sdbc --disable-scripting-beanshell \
--disable-scripting-javascript --disable-largefile --without-helppack-integration \
--without-system-dicts --without-java --disable-gtk3 --disable-dconf --disable-gstreamer-0-10 \
--disable-firebird-sdbc --without-fonts --without-junit --with-theme="no" --disable-evolution2 \
--disable-avahi --without-myspell-dicts --with-galleries="no" \
--disable-kde4 --with-system-expat --with-system-libxml --with-system-nss \
--disable-introspection --without-krb5 --disable-python --disable-pch \
--with-system-openssl --with-system-curl --disable-ooenv --disable-dependency-tracking
make

Reduce the Size

# this will remove ~100 MB of symbols from shared objects
strip ./instdir/**/*
# remove unneeded stuff for headless mode
rm -rf ./instdir/share/gallery \
./instdir/share/config/images_*.zip \
./instdir/readmes \
./instdir/CREDITS.fodt \
./instdir/LICENSE* \
./instdir/NOTICE

Verification

echo "hello world" > a.txt
./instdir/program/soffice --headless --invisible --nodefault --nofirststartwizard \
--nolockcheck --nologo --norestore --convert-to pdf --outdir $(pwd) a.txt

Package

# archive
tar -zcvf lo.tar.gz instdir
docker cp libre-builder:/code/libreoffice/lo.tar.gz ./lo.tar.gz

Gzip vs Zopfli vs Brotli

docker run --name brotli-util --rm -v $(pwd):/root -w /root -d -t ubuntu:18.04 bash
docker exec -t brotli-util apt-get update
docker exec -t brotli-util apt-get install -y brotli
docker exec -t brotli-util gzip -d lo.tar.gz
docker exec -t brotli-util brotli -q 11 -j -f lo.tar

Install Dependencies

docker run --rm --name libreoffice-builder -t -d -v $(pwd):/code --entrypoint /bin/sh aliyunfc/runtime-nodejs8
docker exec -t libreoffice-builder npm install
docker exec -t libreoffice-builder apt-get install -y -d -o=dir::cache=/code libnss3
docker exec -t libreoffice-builder bash -c 'for f in $(ls /code/archives/*.deb); do dpkg -x $f $(pwd) ; done;'
docker exec -t libreoffice-builder bash -c "rm -rf /code/archives/; mkdir -p /code/lib;cd /code/lib; find ../usr/lib -type f \( -name '*.so' -o -name '*.chk' \) -exec ln -sf {} . \;"

Download and Decompress the tar.br Package

ossutil cp $SCRIPT_DIR/../node_modules/fc-libreoffice/bin/lo.tar.br oss://${OSS_BUCKET}/lo.tar.br \
-i ${ALIBABA_CLOUD_ACCESS_KEY_ID} -k ${ALIBABA_CLOUD_ACCESS_KEY_SECRET} -e oss-${ALIBABA_CLOUD_DEFAULT_REGION}.aliyuncs.com -f
module.exports.initializer = (context, callback) => {    store = new OSS({
region: `oss-${process.env.ALIBABA_CLOUD_DEFAULT_REGION}`,
bucket: process.env.OSS_BUCKET,
accessKeyId: context.credentials.accessKeyId,
accessKeySecret: context.credentials.accessKeySecret,
stsToken: context.credentials.securityToken,
internal: process.env.OSS_INTERNAL === 'true'
});
if (fs.existsSync(binPath) === true) {
callback(null, "already downloaded.");
return;
}
co(store.get('lo.tar.br', binPath)).then(function (val) {
callback(null, val)
}).catch(function (err) {
callback(err)
});
};
const {unpack} = require('@shelf/aws-lambda-brotli-unpacker');
const {execSync} = require('child_process');
const inputPath = path.join(__dirname, '..', 'bin', 'lo.tar.br');
const outputPath = '/tmp/instdir/program/soffice';
module.exports.handler = async event => {
await unpack({inputPath, outputPath});
execSync(`${outputPath} --convert-to pdf --outdir /tmp /tmp/example.docx`);
};

Deploy Functions on Fun

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
libre-svc: # service name
Type: 'Aliyun::Serverless::Service'
Properties:
Description: 'fc test'
Policies:
- AliyunOSSFullAccess
libre-fun: # function name
Type: 'Aliyun::Serverless::Function'
Properties:
Handler: index.handler
Initializer: index.initializer
Runtime: nodejs8
CodeUri: './'
Timeout: 60
MemorySize: 640
EnvironmentVariables:
ALIBABA_CLOUD_DEFAULT_REGION: ${ALIBABA_CLOUD_DEFAULT_REGION}
OSS_BUCKET: ${OSS_BUCKET}
OSS_INTERNAL: 'true'
SCRIPT_DIR=`dirname -- "$0"`
source $SCRIPT_DIR/../.env
export ALIBABA_CLOUD_DEFAULT_REGION OSS_BUCKET
envsubst < $SCRIPT_DIR/../template.yml.tpl > $SCRIPT_DIR/../template.yml
cd $SCRIPT_DIR/../

Conclusion

References

  1. https://en.wikipedia.org/wiki/LibreOffice
    2. How to Run LibreOffice in AWS Lambda for Dirty-Cheap PDFs at Scale
    3. https://github.com/alixaxel/chrome-aws-lambda
    4. https://github.com/shelfio/aws-lambda-brotli-unpacker

--

--

--

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

3 ways Kubernetes can make a developer’s life easier

Proof System for VideoCoin Storage Mining

Collaborative Extension: Part 3-Setup Connection from SCP to SAP Jam

Deploying Wordpress Web App on Amazon EKS

The TDD Spectrum — Understand the culture

Introducing DashboardFox: Business Intelligence Software With No Subscriptions

DashboardFox - Alternative to Power BI and Tableau

JWT Authentication and Authorisation in ASP.NET Core Web API

Integrating Docker with Cloud Foundry

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

More from Medium

kafkaVision: An open-source monitoring tool for Apache Kafka

AWS DMS Heartbeat — Avoid Critical Production DB Issues

Cassandra Monitoring Setup Using Open Source Tools

Build flexible abstraction for any Kubernetes Resources with CUE and KubeVela