1
0
Fork 0

Feature/planning 499 different error codes for version check (#3118)

* return different error codes for check-version

* Adds data file for exit codes that can be used by ArangoDB applications

* add some exit codes

* better return codes for centos

* add codes in arangod

* remove test code

* prevent re-downloading of starter and other small improvements

* fix some erros

* finish centos

* update urls

* add info about systemd detection

* move further towards a working systemd setup

* set service type to simple

* add arangodb-update-db script

* start work on debian packages

* a db dir that is already in place (former installation) should be reused now

* fix minor bugs

* Implement exit code translation in the windows installer.

* add autogenerated NSIS exit code mapping
This commit is contained in:
Jan Christoph Uhde 2017-08-30 10:47:31 +02:00 committed by Frank Celler
parent 885ea3dd5f
commit 20e1a673fd
27 changed files with 995 additions and 131 deletions

6
.gitignore vendored
View File

@ -18,6 +18,9 @@ core.*
*.gcno
*.gcda
*.deb
*.rpm
.DS_Store
*.swp
*.diff
@ -110,3 +113,6 @@ data-*
cluster-init
datafile-*.db
# by build process
arangodb-linux-amd64
last_compiled_version.sha

View File

@ -282,9 +282,23 @@ get_filename_component(PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}" REALPATH)
set($ENV{PYTHON_EXECUTABLE} ${PYTHON_EXECUTABLE})
# FIXME the build containers seem to have a
# /usr/bin/ch(mod|own) to prevent the search
# to find those files the NO_DEFAULT_PATH
# argument is passed
if (NOT WINDOWS)
find_program(CHMOD_EXECUTABLE chmod)
find_program(CHOWN_EXECUTABLE chown)
find_program(
CHMOD_EXECUTABLE chmod
PATHS "/bin/" "/usr/bin/"
NO_DEFAULT_PATH
)
message(STATUS "chmod found in ${CHMOD_EXECUTABLE}")
find_program(
CHOWN_EXECUTABLE chown
PATHS "/bin" "/usr/bin"
NO_DEFAULT_PATH
)
message(STATUS "chown found in ${CHOWN_EXECUTABLE}")
endif()
################################################################################
@ -894,6 +908,33 @@ if (USE_MAINTAINER_MODE)
endforeach ()
add_custom_target(errorfiles ALL DEPENDS ${ERROR_FILES_GEN})
set(EXIT_CODE_FILES
lib/Basics/exitcodes.h
lib/Basics/exitcodes.cpp
js/common/bootstrap/exitcodes.js
Installation/Windows/Plugins/exitcodes.nsh
)
set(EXIT_CODE_FILES_GEN)
set(EXIT_CODES_DAT lib/Basics/exitcodes.dat)
foreach (m IN LISTS EXIT_CODE_FILES)
add_custom_command(
OUTPUT ${CMAKE_SOURCE_DIR}/${m}
COMMAND ${PYTHON_EXECUTABLE} ./utils/generateExitCodesFiles.py ./${EXIT_CODES_DAT} ./${m}.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different ./${m}.tmp ./${m}
COMMAND ${CMAKE_COMMAND} -E remove ./${m}.tmp
DEPENDS ${CMAKE_SOURCE_DIR}/${EXIT_CODES_DAT}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Building exitcode files ${m}"
VERBATIM
)
list(APPEND EXIT_CODE_FILES_GEN ${CMAKE_SOURCE_DIR}/${m})
endforeach ()
add_custom_target(exitcodefiles ALL DEPENDS ${EXIT_CODE_FILES_GEN})
endif ()
################################################################################

View File

@ -656,10 +656,18 @@ if test "${DOWNLOAD_STARTER}" == 1; then
if test -f "${TN}"; then
rm -f "${TN}"
fi
curl -LO "${STARTER_URL}"
FN=$(echo "${STARTER_URL}" |${SED} "s;.*/;;")
mv "${FN}" "${BUILD_DIR}/${TN}"
chmod a+x "${BUILD_DIR}/${TN}"
echo $FN
if ! test -f "${BUILD_DIR}/${FN}-${STARTER_REV}"; then
curl -LO "${STARTER_URL}"
cp "${FN}" "${BUILD_DIR}/${TN}"
touch "${BUILD_DIR}/${FN}-${STARTER_REV}"
chmod a+x "${BUILD_DIR}/${TN}"
echo "downloaded ${BUILD_DIR}/${FN}-${STARTER_REV} MD5: $(${MD5} < "${BUILD_DIR}/${TN}")"
else
echo "using already downloaded ${BUILD_DIR}/${FN}-${STARTER_REV} MD5: $(${MD5} < "${BUILD_DIR}/${TN}")"
fi
fi
CONFIGURE_OPTIONS+=("-DTHIRDPARTY_BIN=${BUILD_DIR}/${TN}")
fi

View File

@ -0,0 +1,75 @@
!include "LogicLib.nsh"
!macro printExitCode exitCode Message
Push "${exitCode}"
Push "${Message}"
Call printExitCode
!macroend
Function printExitCode
pop $1
pop $2
${Switch} $0
${Case} 0 # EXIT_SUCCESS
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nsuccess'
; No error has occurred.
${Break}
${Case} 1 # EXIT_FAILED
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nexit with error'
; Will be returned when a general error occurred.
${Break}
${Case} 2 # EXIT_CODE_RESOLVING_FAILED
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nexit code resolving failed'
; fill me
${Break}
${Case} 5 # EXIT_BINARY_NOT_FOUND
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nbinary not found'
; fill me
${Break}
${Case} 6 # EXIT_CONFIG_NOT_FOUND
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nconfig not found'
; fill me
${Break}
${Case} 10 # EXIT_UPGRADE_FAILED
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nupgrade failed'
; Will be returned when the database upgrade failed
${Break}
${Case} 11 # EXIT_UPGRADE_REQUIRED
MessageBox MB_ICONEXCLAMATION '$1:$\r$\ndb upgrade required'
; Will be returned when a database upgrade is required
${Break}
${Case} 12 # EXIT_DOWNGRADE_REQUIRED
MessageBox MB_ICONEXCLAMATION '$1:$\r$\ndb downgrade required'
; Will be returned when a database upgrade is required
${Break}
${Case} 13 # EXIT_VERSION_CHECK_FAILED
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nversion check failed'
; Will be returned when there is a version mismatch
${Break}
${Case} 20 # EXIT_ALREADY_RUNNING
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nalready running'
; Will be returned when arangod is already running according to PID-file
${Break}
${Case} 21 # EXIT_COULD_NOT_BIND_PORT
MessageBox MB_ICONEXCLAMATION '$1:$\r$\nport blocked'
; Will be returned when endpoint is taken by another process
${Break}
${Case} 22 # EXIT_COULD_NOT_LOCK
MessageBox MB_ICONEXCLAMATION '$1:$\r$\ncould not lock - another process could be running'
; fill me
${Break}
${EndSwitch}
FunctionEnd

View File

@ -5,6 +5,7 @@
!addincludedir '@CPACK_PLUGIN_PATH@/UAC-plug-in-NSIS'
!addincludedir '@CPACK_PLUGIN_PATH@/'
!include "OpenLink.nsh"
!include "exitcodes.nsh"
;--------------------------------
; Include LogicLib for more readable code
@ -718,7 +719,10 @@ Function UpgradeExisting
DetailPrint "Checking whether an existing database needs upgrade: "
ExecWait "$INSTDIR\${SBIN_DIR}\arangod.exe --server.rest-server false --log.foreground-tty false --database.check-version" $0
DetailPrint "done Checking whether an existing database needs upgrade: $0"
${If} $0 == 1
${If} $0 != 0
${AndIf} $0 != 11
!insertmacro printExitCode $0 "failed to detect whether we need to Upgrade"
${ElseIf} $0 == 11
${AndIf} $AUTOMATIC_UPDATE == "1"
DetailPrint "Yes."
@ -740,8 +744,8 @@ Function UpgradeExisting
; Now actually do the upgrade
ExecWait "$INSTDIR\${SBIN_DIR}\arangod.exe --server.rest-server false --log.level error --database.auto-upgrade true" $0
DetailPrint "Done running database upgrade: $0"
${If} $0 == 1
MessageBox MB_ICONEXCLAMATION "the Upgrade failed, please do a manual upgrade"
${If} $0 != 0
!insertmacro printExitCode $0 "the Upgrade failed, please do a manual upgrade"
Abort
${EndIf}
${EndIf}
@ -757,6 +761,9 @@ Function SetDBPassword
DetailPrint "Done initializing password: $0"
${If} $0 == 0
return
${Else}
!insertmacro printExitCode $0 "Failed to initialize database password.$\r$\nPlease check the windows event log for more details$\r$\n"
Abort
${EndIf}
error:
MessageBox MB_OK "Failed to initialize database password.$\r$\nPlease check the windows event log for details."

View File

@ -0,0 +1,146 @@
#!/bin/sh
# os detection
ar_detect_os(){
local file="/etc/centos-release"
local os="unknown release"
if [ -f "$file" ]; then
os="centos"
if grep -q -s " 6" "$file" &>/dev/null ; then
os+="6"
elif grep -q -s " 7" "$file" &>/dev/null ; then
os+="7"
fi
fi
echo "$os"
#debian
#opensuse
#mac
}
#export detected os
export ARANGO_OS="$(ar_detect_os)"
#print error message
ar_err(){
local msg="$1"
local code="${2-1}"
if ! [ $code -eq 0 ]; then
echo "ERROR: $msg" 1>&2
fi
}
#print fatal error message and exit
ar_ferr(){
local code="${2-1}"
if ! [ $code -eq 0 ]; then
local msg="$1"
echo "FATAL ERROR: $msg" 1>&2
exit "$code"
fi
}
## exit codes and other data
#function for searching .dat files
ar_find_dat_file(){
local name="$1"
local found=false
for p in "/usr/share/arangodb3" "some other path"; do
local full_path="$p/$name"
if [ -f "$full_path" ]; then
found=true
echo "$full_path"
break
fi
done
if ! $found; then
echo "$could not find datafile $name"
fi
}
export ARANGO_ERROR_CODES_DAT="$(ar_find_dat_file exitcodes.dat)"
ar_exitcode_num_to_string(){
in="$1"
local file="$ARANGO_ERROR_CODES_DAT"
local found=false
if [ -f "$file" ]; then
while IFS=',' read code num _ ; do
if [ "$in" == "$num" ]; then
echo $code
found=true
break
fi
done < "$file"
else
echo "EXIT_CODE_RESOLVING_FAILED for code $in"
fi
if ! $found; then
echo "EXIT_CODE_RESOLVING_FAILED for code $in"
fi
}
ar_exitcode_num_to_message(){
local in="$1"
if [[ $in == "0" ]]; then
return
fi
local file="$ARANGO_ERROR_CODES_DAT"
local found=false
if [ -f $file ]; then
while IFS=',' read code num message long_message; do
if [ "$in" == "$num" ]; then
echo "$message"
found=true
break
fi
done < "$file"
else
echo "could not resolve exit code $in"
fi
if ! $found; then
echo "could not resolve exit code $in"
fi
}
ar_exitcode_string_to_num(){
local file="$ARANGO_ERROR_CODES_DAT"
local found=false
if [ -f $file ]; then
in="$1"
while IFS=',' read code num _ ; do
if [ "$in" == "$code" ]; then
echo $num
found=true
break
fi
done < "$file"
else
echo 2
fi
if ! $found; then
echo 2
fi
}
ar_exit_by_num(){
local code="$1"
local str="$(ar_exitcode_num_to_string $code)"
local msg="$(ar_exitcode_num_to_message $code)"
if [ $code -ne 0 ]; then
echo "FATAL ERROR: $str - $msg" 1>&2
exit "$code"
fi
}
ar_exit_by_string(){
local code=$(ar_exitcode_string_to_num "$1")
ar_exit_by_num $code
}

View File

@ -0,0 +1,8 @@
#!/bin/sh
#update db
/usr/sbin/arangod --uid arangodb --gid arangodb --pid-file /var/run/arangodb3/arangod.pid --server.rest-server false --database.auto-upgrade true
rv=$?
. /usr/share/arangodb3/arangodb-helper
ar_exit_by_num $rv

View File

@ -1,81 +1,91 @@
#!/bin/sh
set -e
action="$1"
version="$2"
# source debconf stuff
. /usr/share/debconf/confmodule
db_version 2.0
db_capb backup
db_capb backup
DO_CONFIGURE=no
if test -n "$2"; then
# do we want to reconfigure?
if test "`echo $2 | sed -e 's/[a-zA-Z.-]//g' -e 's;ubuntu;;'`" -lt 127 \
-o "$1" = reconfigure
then
DO_CONFIGURE=yes
if test -n "$version"; then
# do we want to reconfigure?
short_version="$(echo "$version" | sed -e 's/[a-zA-Z.-]//g' -e 's;ubuntu;;')"
if test "$short_version" -lt 127 -o "$action" = reconfigure; then
DO_CONFIGURE=yes
fi
else
# are we in first install?
if test "$1" = "configure"; then
DO_CONFIGURE=yes
else
# are we in first install?
if test "$action" = "configure"; then
DO_CONFIGURE=yes
fi
fi
#do the actual configure
if test "$DO_CONFIGURE" = "yes"; then
STATE=1
LASTSTATE=5
while [ "$STATE" != 0 -a "$STATE" -le "$LASTSTATE" ]; do
while test "$STATE" -ne 0 -a \
"$STATE" -le "$LASTSTATE" ; do
case "$STATE" in
1)
db_input high @CPACK_PACKAGE_NAME@/password || true
case "$STATE" in
1)
db_input high @CPACK_PACKAGE_NAME@/password || true
db_go
db_get @CPACK_PACKAGE_NAME@/password
#if [ -z "$RET" ]; then
#fi
ROOT_PW="$RET"
;;
;;
2)
db_input high @CPACK_PACKAGE_NAME@/password_again || true
db_input high @CPACK_PACKAGE_NAME@/password_again || true
db_go
db_get @CPACK_PACKAGE_NAME@/password_again
if [ "$ROOT_PW" = "$RET" ]; then
ROOT_PW=""
else
db_input critical @CPACK_PACKAGE_NAME@/password_mismatch
STATE=$(($STATE - 2))
STATE=$(($STATE - 2))
db_set @CPACK_PACKAGE_NAME@/password_again ""
fi
;;
3)
;;
3)
db_input high @CPACK_PACKAGE_NAME@/upgrade || true
;;
;;
4)
db_input high @CPACK_PACKAGE_NAME@/storage_engine || true
db_go
;;
5)
;;
5)
db_get @CPACK_PACKAGE_NAME@/upgrade
if [ "$RET" = "true" ]; then
db_input high @CPACK_PACKAGE_NAME@/backup || true
db_go
else
db_set @CPACK_PACKAGE_NAME@/backup "false"
fi
;;
;;
esac
if db_go; then
STATE=$(($STATE + 1))
else
STATE=$(($STATE - 1))
fi
done
esac
if db_go; then
STATE=$((STATE + 1))
else
STATE=$((STATE - 1))
fi
done # STATE LOOP
fi # DO_CONFIGURE
# test if db-dir is in place but arangod is not installed if
# so try an upgrade
if test -d /var/lib/arangodb3 -a ! -f /usr/sbin/arangod; then
db_set @CPACK_PACKAGE_NAME@/new_install_existing_db_dir "true"
else
db_set @CPACK_PACKAGE_NAME@/new_install_existing_db_dir "false"
fi
exit 0

View File

@ -3,7 +3,7 @@ the multi-model NoSQL database
graphs, and key-values. Build high performance applications using a convenient
SQL-like query language or JavaScript extensions.
.
Copyright: 2014-2016 by ArangoDB GmbH
Copyright: 2014-2017 by ArangoDB GmbH
Copyright: 2012-2013 by triAGENS GmbH
ArangoDB Software
www.arangodb.com

View File

@ -1,45 +1,60 @@
#!/bin/sh
set -e
action="$1"
ARANGODB="/usr/sbin/arangod"
# source debconf library
. /usr/share/debconf/confmodule
set +x
db_get @CPACK_PACKAGE_NAME@/storage_engine
STORAGE_ENGINE=$RET
export GLIBCXX_FORCE_NEW=1
db_get @CPACK_PACKAGE_NAME@/new_install_existing_db_dir
NEW_INSTALL_EXISTING_DIR=$RET
#fill in correct storage engine into arangod.conf
sed -i /etc/arangodb3/arangod.conf -e "s;storage-engine = auto;storage-engine = $STORAGE_ENGINE;"
if [ "$1" = "configure" -a -z "$2" ]; then
if test "$action" = "configure" -a \
-z "$2" -a \
"$NEW_INSTALL_EXISTING_DIR" = "false" ; then
db_get @CPACK_PACKAGE_NAME@/password
# Escape backslashes and quotes
if [ -n "$RET" ]; then
ARANGODB_DEFAULT_ROOT_PASSWORD=`echo "$RET"|sed -e 's;\\\\;\\\\\\\\;g' -e 's;";\\\\";g'` \
/usr/sbin/arango-init-database \
--server.rest-server false \
--server.statistics false --foxx.queues false \
--uid arangodb --gid arangodb || true
ARANGODB_DEFAULT_ROOT_PASSWORD="$(echo "$RET" | sed -e 's;\\\\;\\\\\\\\;g' -e 's;";\\\\";g')" \
/usr/sbin/arango-init-database \
--server.rest-server false \
--server.statistics false --foxx.queues false \
--uid arangodb --gid arangodb || true
fi
db_set @CPACK_PACKAGE_NAME@/password_again ""
db_set @CPACK_PACKAGE_NAME@/password ""
db_go
fi
# check if we should upgrade the database directory
UPGRADE=false
$ARANGODB --uid arangodb --gid arangodb --server.rest-server false --log.foreground-tty false --database.check-version \
UPGRADE=false #requires upgrade
$ARANGODB --uid arangodb --gid arangodb \
--server.rest-server false --log.foreground-tty false
--database.check-version \
|| UPGRADE=true
db_get @CPACK_PACKAGE_NAME@/upgrade
db_get @CPACK_PACKAGE_NAME@/upgrade #wants upgrade
if [ "$RET" = "true" ]; then
if [ "$UPGRADE" = "true" ]; then
db_get @CPACK_PACKAGE_NAME@/backup
if [ "$RET" = "true" ]; then
BACKUP="/var/lib/arangodb3-`date +%F-%H-%M-%S`"
cp -a /var/lib/arangodb3 $BACKUP
BACKUP="/var/lib/arangodb3-$(date +%F-%H-%M-%S)"
cp -a /var/lib/arangodb3 "$BACKUP"
echo "A backup of your database files has been stored in $BACKUP."
fi
@ -51,7 +66,7 @@ if [ "$RET" = "true" ]; then
elif [ "$UPGRADE" = "true" ]; then
echo "Warning: database files need upgrade, automatic upgrade is disable, please do it manually."
echo "After you've prepared your system for upgrade run "
echo " /etc/init.d/arangodb3 upgrade"
echo " /usr/share/arangodb3/arangodb-update-db"
echo " dpkg --pending --configure"
echo "after the packaging system is in stable state again."
else

View File

@ -227,13 +227,13 @@ ArangoDB 3 (https://www.arangodb.com)
or JavaScript extensions.
First Steps with ArangoDB:
https://www.arangodb.com/quickstart
https://docs.arangodb.com/latest/Manual/GettingStarted/
Upgrading ArangoDB:
https://docs.arangodb.com/Installing/Upgrading.html
Configuring the storage Engine:
https://docs.arangodb.com/3.2/Manual/Administration/Configuration/GeneralArangod.html#storage-engine
https://docs.arangodb.com/latest/Manual/Administration/Configuration/GeneralArangod.html#storage-engine
Upgrading ArangoDB database files:
> /etc/init.d/arangodb3 upgrade
@ -262,9 +262,8 @@ export ARANGODB_DEFAULT_ROOT_PASSWORD=`(uname -a ; cat /etc/hostname) | md5sum |
echo "SECURITY HINT:"
echo "run 'arango-secure-installation' to set a root password"
echo "the current password is $ARANGODB_DEFAULT_ROOT_PASSWORD"
echo "(in case this a FRESH install, for UPGRADE the password"
echo "will not be changed)"
echo "the current password is '$ARANGODB_DEFAULT_ROOT_PASSWORD'"
echo "(You should do this for a FRESH install! For an UPGRADE the password does not need to be changed)"
/usr/sbin/arango-init-database --uid arangodb --gid arangodb --server.rest-server false --server.statistics false --foxx.queues false || true

View File

@ -9,13 +9,14 @@
# Source function library.
. /etc/rc.d/init.d/functions
. /usr/share/arangodb3/arangodb-helper
# Path to the server binary
ARANGO_BIN=/usr/sbin/arangod
test -x $ARANGO_BIN || exit 5
test -x $ARANGO_BIN || ar_exit_by_string EXIT_BINARY_NOT_FOUND
ARANGO_SYSCONFIG=/etc/arangodb3/arangod.conf
test -r $ARANGO_SYSCONFIG || exit 6
test -r $ARANGO_SYSCONFIG || ar_exit_by_string EXIT_CONFIG_NOT_FOUND
pidfile=/var/run/arangodb/arangod.pid
@ -25,12 +26,11 @@ start() {
echo -n $"Starting $ARANGO_BIN: "
PIDDIR=`dirname $pidfile`
[ -d $PIDDIR ] || mkdir $PIDDIR || exit 1
[ -d $PIDDIR ] || mkdir $PIDDIR || ar_ferr "failed to create $PIDDIR"
( cd /var/log/arangodb3 && chown -R arangodb:arangodb . && chmod 700 .) || exit 1
( cd /var/lib/arangodb3 && chown -R arangodb:arangodb . && chmod 700 .) || exit 1
( cd /var/lib/arangodb3-apps && chown -R arangodb:arangodb . && chmod 700 .) || exit 1
( cd $PIDDIR && chown arangodb:arangodb . && chmod 700 .) || exit 1
( cd /var/lib/arangodb3 && chown -R arangodb:arangodb . && chmod 700 .) || ar_ferr "failed to set permissions on /var/lib/arangodb3"
( cd /var/lib/arangodb3-apps && chown -R arangodb:arangodb . && chmod 700 .) || ar_ferr "failed to set permissions on /var/lib/arangodb3-apps"
( cd $PIDDIR && chown arangodb:arangodb . && chmod 700 .) || ar_ferr "failed to set permissions on $PIDDIR"
ulimit -H -n 131072 || true
ulimit -S -n 131072 || true
@ -58,14 +58,11 @@ start() {
if [ "$RETVAL" -eq 0 ]; then
$ARANGO_BIN --uid arangodb --gid arangodb --log.foreground-tty false --pid-file "$pidfile" --temp.path "/var/tmp/arangod" --supervisor $@
RETVAL=$?
else
echo "database version check failed, maybe you need to run 'upgrade'?"
fi
;;
esac
echo
return $RETVAL
ar_exit_by_num ${RETVAL}
}
@ -73,12 +70,8 @@ start() {
stop() {
echo -n $"Stopping $ARANGO_BIN: "
killproc -p "${pidfile}" -d 10 $ARANGO_BIN
RETVAL=$?
echo "$RETVAL"
if test "$RETVAL" -ne "0" ; then
exit "$RETVAL"
fi
ar_ferr "could not kill arangod" $RETVAL
}
@ -98,7 +91,7 @@ case "$1" in
;;
restart)
stop || exit 1
stop # will exit on fail
start
;;
@ -107,7 +100,7 @@ case "$1" in
start --upgrade
;;
reload-log)
log_daemon_msg "Re-Opening Logfiles $DESC" "$NAME"

View File

@ -17,10 +17,14 @@ Description=ArangoDB database server
After=sysinit.target sockets.target timers.target paths.target slices.target network.target syslog.target
[Service]
Type=forking
Type=simple
LimitNOFILE=131072
PIDFile=/var/run/arangodb3/arangod.pid
Environment=GLIBCXX_FORCE_NEW=1
# Protect users from making their installation unusable by
# starting arangod with wrong permissions (e.g. as root).
# This will reset the permissions to the working default.
ExecStartPre=/usr/bin/install -g arangodb -o arangodb -d /var/tmp/arangodb3
ExecStartPre=/usr/bin/install -g arangodb -o arangodb -d /var/run/arangodb3
ExecStartPre=@CHOWN_EXECUTABLE@ -R arangodb:arangodb /var/log/arangodb3
@ -29,11 +33,13 @@ ExecStartPre=@CHOWN_EXECUTABLE@ -R arangodb:arangodb /var/lib/arangodb3
ExecStartPre=@CHMOD_EXECUTABLE@ 700 /var/lib/arangodb3
ExecStartPre=@CHOWN_EXECUTABLE@ -R arangodb:arangodb /var/lib/arangodb3-apps
ExecStartPre=@CHMOD_EXECUTABLE@ 700 /var/lib/arangodb3-apps
ExecStartPre=/usr/sbin/arangod --uid arangodb --gid arangodb --pid-file /var/run/arangodb3/arangod.pid --server.rest-server false --database.auto-upgrade true
ExecStart=/usr/sbin/arangod --uid arangodb --gid arangodb --pid-file /var/run/arangodb3/arangod.pid --temp.path /var/tmp/arangodb3 --supervisor --log.foreground-tty false
ExecStart=/usr/sbin/arangod --uid arangodb --gid arangodb --pid-file /var/run/arangodb3/arangod.pid --temp.path /var/tmp/arangodb3 --log.foreground-tty true
TimeoutStopSec=3600
TimeoutSec=3600
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

View File

@ -26,6 +26,7 @@
#include "Basics/ConditionLocker.h"
#include "Basics/MutexLocker.h"
#include "Basics/exitcodes.h"
#include "Endpoint/EndpointList.h"
#include "GeneralServer/GeneralDefinitions.h"
#include "GeneralServer/GeneralListenTask.h"
@ -68,7 +69,7 @@ void GeneralServer::startListening() {
<< "'. Please check whether another instance is already "
"running using this endpoint and review your endpoints "
"configuration.";
FATAL_ERROR_EXIT();
FATAL_ERROR_EXIT_CODE(TRI_EXIT_COULD_NOT_BIND_PORT);
}
}
}

View File

@ -32,6 +32,7 @@
#include "V8Server/v8-query.h"
#include "V8Server/v8-vocbase.h"
#include "VocBase/vocbase.h"
#include "Basics/exitcodes.h"
using namespace arangodb;
using namespace arangodb::application_features;
@ -154,7 +155,7 @@ void CheckVersionFeature::checkVersion() {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Database version check failed for '"
<< vocbase->name()
<< "'. Please inspect the logs for any errors";
FATAL_ERROR_EXIT();
FATAL_ERROR_EXIT_CODE(TRI_EXIT_VERSION_CHECK_FAILED);
} else if (status == 3) {
// this is safe to do even if further databases will be checked
// because we will never set the status back to success
@ -182,8 +183,17 @@ void CheckVersionFeature::checkVersion() {
if (*_result == 1) {
*_result = EXIT_SUCCESS;
} else if (*_result > 1) {
*_result = EXIT_FAILURE;
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Database version check failed";
FATAL_ERROR_EXIT();
if (*_result == 2) {
// downgrade needed
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Database version check failed: downgrade needed";
FATAL_ERROR_EXIT_CODE(TRI_EXIT_DOWNGRADE_REQUIRED);
} else if (*_result == 3) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Database version check failed: upgrade needed";
FATAL_ERROR_EXIT_CODE(TRI_EXIT_UPGRADE_REQUIRED);
} else {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Database version check failed";
FATAL_ERROR_EXIT_CODE(TRI_EXIT_VERSION_CHECK_FAILED);
}
FATAL_ERROR_EXIT_CODE(*_result);
}
}

View File

@ -24,6 +24,7 @@
#include "Basics/Exceptions.h"
#include "Basics/FileUtils.h"
#include "Basics/files.h"
#include "Basics/exitcodes.h"
#include "Logger/Logger.h"
#include "RestServer/DatabasePathFeature.h"
@ -58,7 +59,7 @@ void LockfileFeature::start() {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "database is locked by process " <<
otherPID << "; please stop it first and check that the lockfile '" << _lockFilename << "' goes away. If you are sure no other arangod process is running, please remove the lockfile '" << _lockFilename << "' and try again";
}
FATAL_ERROR_EXIT();
FATAL_ERROR_EXIT_CODE(TRI_EXIT_COULD_NOT_LOCK);
}
if (TRI_ExistsFile(_lockFilename.c_str())) {
@ -68,7 +69,7 @@ void LockfileFeature::start() {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "failed to remove an abandoned lockfile in the database directory, please check the file permissions of the lockfile '"
<< _lockFilename << "': " << TRI_errno_string(res);
FATAL_ERROR_EXIT();
FATAL_ERROR_EXIT_CODE(TRI_EXIT_COULD_NOT_LOCK);
}
}
res = TRI_CreateLockFile(_lockFilename.c_str());
@ -77,7 +78,7 @@ void LockfileFeature::start() {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "failed to lock the database directory using '"
<< _lockFilename << "': " << TRI_errno_string(res);
FATAL_ERROR_EXIT();
FATAL_ERROR_EXIT_CODE(TRI_EXIT_COULD_NOT_LOCK);
}
}

View File

@ -131,8 +131,6 @@ install(
### @brief detect if we're on a systemd enabled system; if install unit file.
################################################################################
set(IS_SYSTEMD_INSTALL 0)
set(SYSTEMD_UNIT_DIR "")
if (UNIX)
if (${USE_ENTERPRISE})
set(SERVICE_NAME "arangodb3e")
@ -140,42 +138,68 @@ if (UNIX)
set(SERVICE_NAME "arangodb3")
endif ()
# use pkgconfig for systemd detection
find_package(PkgConfig QUIET)
pkg_check_modules(SYSTEMD systemd)
if (SYSTEMD_FOUND)
# cmake to old: pkg_get_variable(SYSTEMD_UNIT_DIR systemd systemdsystemunitdir)
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} systemd --variable=systemdsystemunitdir
OUTPUT_VARIABLE SYSTEMD_UNIT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(IS_SYSTEMD_INSTALL 1)
configure_file (
${ARANGODB_SOURCE_DIR}/Installation/systemd/arangodb3.service.in
${PROJECT_BINARY_DIR}/arangodb3.service
NEWLINE_STYLE UNIX)
if (CMAKE_INSTALL_PREFIX AND NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
set(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/${SYSTEMD_UNIT_DIR}/")
endif()
install(FILES ${PROJECT_BINARY_DIR}/arangodb3.service
DESTINATION ${SYSTEMD_UNIT_DIR}/
RENAME ${SERVICE_NAME}.service)
configure_file (
${ARANGODB_SOURCE_DIR}/Installation/logrotate.d/arangod.systemd
${PROJECT_BINARY_DIR}/arangod.systemd
NEWLINE_STYLE UNIX)
install(
FILES ${PROJECT_BINARY_DIR}/arangod.systemd
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/logrotate.d
RENAME ${SERVICE_NAME})
else ()
configure_file (
${ARANGODB_SOURCE_DIR}/Installation/logrotate.d/arangod.sysv
${PROJECT_BINARY_DIR}/arangod.sysv
NEWLINE_STYLE UNIX)
endif()
endif()
if(NOT PKG_CONFIG_FOUND)
message(STATUS "pkg-config not found - skipping systemd detection")
else()
set(IS_SYSTEMD_INSTALL 0)
set(SYSTEMD_UNIT_DIR "")
message(STATUS "detecting systemd")
pkg_check_modules(SYSTEMD systemd)
if (SYSTEMD_FOUND)
message(STATUS "-- systemd found")
# get systemd_unit_dir -- e.g /lib/systemd/system/
# cmake to old: pkg_get_variable(SYSTEMD_UNIT_DIR systemd systemdsystemunitdir)
execute_process(
COMMAND ${PKG_CONFIG_EXECUTABLE} systemd --variable=systemdsystemunitdir
OUTPUT_VARIABLE SYSTEMD_UNIT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(IS_SYSTEMD_INSTALL 1)
# set prefix
if (CMAKE_INSTALL_PREFIX AND NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
set(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/${SYSTEMD_UNIT_DIR}/")
endif()
# configure and install systemd service
configure_file (
${ARANGODB_SOURCE_DIR}/Installation/systemd/arangodb3.service.in
${PROJECT_BINARY_DIR}/arangodb3.service
NEWLINE_STYLE UNIX
)
install(
FILES ${PROJECT_BINARY_DIR}/arangodb3.service
DESTINATION ${SYSTEMD_UNIT_DIR}/
RENAME ${SERVICE_NAME}.service
)
# configure and install logrotate file
configure_file (
${ARANGODB_SOURCE_DIR}/Installation/logrotate.d/arangod.systemd
${PROJECT_BINARY_DIR}/arangod.systemd
NEWLINE_STYLE UNIX
)
install(
FILES ${PROJECT_BINARY_DIR}/arangod.systemd
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/logrotate.d
RENAME ${SERVICE_NAME}
)
else ()
message(STATUS "-- systemd not found")
configure_file (
${ARANGODB_SOURCE_DIR}/Installation/logrotate.d/arangod.sysv
${PROJECT_BINARY_DIR}/arangod.sysv
NEWLINE_STYLE UNIX
)
endif(SYSTEMD_FOUND)
endif(NOT PKG_CONFIG_FOUND)
endif(UNIX)
################################################################################
### @brief propagate the locations into our programms:
################################################################################
@ -203,6 +227,19 @@ install(FILES ${ICU_DT}
DESTINATION "${INSTALL_ICU_DT_DEST}"
RENAME ${ICU_DT_DEST})
install(FILES "${CMAKE_SOURCE_DIR}/lib/Basics/exitcodes.dat"
DESTINATION "${INSTALL_ICU_DT_DEST}"
RENAME exitcodes.dat)
install(FILES "${CMAKE_SOURCE_DIR}/Installation/arangodb-helper"
DESTINATION "${INSTALL_ICU_DT_DEST}"
RENAME arangodb-helper)
install(FILES "${CMAKE_SOURCE_DIR}/Installation/arangodb-helper"
DESTINATION "${INSTALL_ICU_DT_DEST}"
RENAME arangodb-update-db)
if (MSVC AND NOT(SKIP_PACKAGING))
# so we don't need to ship dll's twice, make it one directory:
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/InstallMacros.cmake)

View File

@ -0,0 +1,27 @@
/*jshint maxlen: 240 */
/*global require */
////////////////////////////////////////////////////////////////////////////////
/// @brief auto-generated file generated from exitcodes.dat
////////////////////////////////////////////////////////////////////////////////
(function () {
"use strict";
var internal = require("internal");
internal.exitCodes = {
"EXIT_SUCCESS" : { "code" : 0, "message" : "success" },
"EXIT_FAILED" : { "code" : 1, "message" : "exit with error" },
"EXIT_CODE_RESOLVING_FAILED" : { "code" : 2, "message" : "exit code resolving failed" },
"EXIT_BINARY_NOT_FOUND" : { "code" : 5, "message" : "binary not found" },
"EXIT_CONFIG_NOT_FOUND" : { "code" : 6, "message" : "config not found" },
"EXIT_UPGRADE_FAILED" : { "code" : 10, "message" : "upgrade failed" },
"EXIT_UPGRADE_REQUIRED" : { "code" : 11, "message" : "db upgrade required" },
"EXIT_DOWNGRADE_REQUIRED" : { "code" : 12, "message" : "db downgrade required" },
"EXIT_VERSION_CHECK_FAILED" : { "code" : 13, "message" : "version check failed" },
"EXIT_ALREADY_RUNNING" : { "code" : 20, "message" : "already running" },
"EXIT_COULD_NOT_BIND_PORT" : { "code" : 21, "message" : "port blocked" },
"EXIT_COULD_NOT_LOCK" : { "code" : 22, "message" : "could not lock - another process could be running" }
};
}());

View File

@ -212,13 +212,20 @@ typedef long suseconds_t;
/// @brief aborts program execution, returning an error code
/// if backtraces are enabled, a backtrace will be printed before
#define FATAL_ERROR_EXIT(...) \
#define FATAL_ERROR_EXIT_CODE(code) \
do { \
TRI_LogBacktrace(); \
arangodb::Logger::flush(); \
arangodb::Logger::shutdown(); \
TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr); \
exit(EXIT_FAILURE); \
TRI_EXIT_FUNCTION(code, nullptr); \
exit(code); \
} while (0)
/// @brief aborts program execution, returning an error code
/// if backtraces are enabled, a backtrace will be printed before
#define FATAL_ERROR_EXIT(...) \
do { \
FATAL_ERROR_EXIT_CODE(EXIT_FAILURE); \
} while (0)
/// @brief aborts program execution, calling std::abort

View File

@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "Basics/Common.h"
#include "Basics/exitcodes.h"
/// @brief error number and system error
struct ErrorContainer {
@ -34,6 +35,8 @@ thread_local ErrorContainer LastError;
/// @brief the error messages, will be read-only after initialization
static std::unordered_map<int, char const*> ErrorMessages;
static std::unordered_map<int, char const*> ExitMessages;
/// @brief returns the last error
int TRI_errno() { return LastError._number; }
@ -62,6 +65,16 @@ int TRI_set_errno(int error) {
return error;
}
/// @brief defines an exit code string
void TRI_set_exitno_string(int code, char const* msg) {
if (!ExitMessages.emplace(code, msg).second) {
// logic error, error number is redeclared
printf("Error: duplicate declaration of exit code %i in %s:%i\n", code,
__FILE__, __LINE__);
TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
}
}
/// @brief defines an error string
void TRI_set_errno_string(int code, char const* msg) {
if (!ErrorMessages.emplace(code, msg).second) {
@ -87,6 +100,7 @@ char const* TRI_errno_string(int code) {
/// @brief initializes the error messages
void TRI_InitializeError() {
TRI_InitializeErrorMessages();
TRI_InitializeExitMessages();
}
/// @brief shuts down the error messages

View File

@ -70,4 +70,10 @@ void TRI_InitializeError();
void TRI_ShutdownError();
////////////////////////////////////////////////////////////////////////////////
/// @brief defines an exit string
////////////////////////////////////////////////////////////////////////////////
void TRI_set_exitno_string(int, char const*);
#endif

21
lib/Basics/exitcodes.cpp Normal file
View File

@ -0,0 +1,21 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief auto-generated file generated from exitcodes.dat
////////////////////////////////////////////////////////////////////////////////
#include "Basics/Common.h"
#include "./lib/Basics/exitcodes.h"
void TRI_InitializeExitMessages () {
REG_EXIT(EXIT_SUCCESS, "success");
REG_EXIT(EXIT_FAILED, "exit with error");
REG_EXIT(EXIT_CODE_RESOLVING_FAILED, "exit code resolving failed");
REG_EXIT(EXIT_BINARY_NOT_FOUND, "binary not found");
REG_EXIT(EXIT_CONFIG_NOT_FOUND, "config not found");
REG_EXIT(EXIT_UPGRADE_FAILED, "upgrade failed");
REG_EXIT(EXIT_UPGRADE_REQUIRED, "db upgrade required");
REG_EXIT(EXIT_DOWNGRADE_REQUIRED, "db downgrade required");
REG_EXIT(EXIT_VERSION_CHECK_FAILED, "version check failed");
REG_EXIT(EXIT_ALREADY_RUNNING, "already running");
REG_EXIT(EXIT_COULD_NOT_BIND_PORT, "port blocked");
REG_EXIT(EXIT_COULD_NOT_LOCK, "could not lock - another process could be running");
}

27
lib/Basics/exitcodes.dat Executable file
View File

@ -0,0 +1,27 @@
################################################################################
## Exit Codes
################################################################################
# general
EXIT_SUCCESS,0,"success","No error has occurred."
EXIT_FAILED,1,"exit with error","Will be returned when a general error occurred."
EXIT_CODE_RESOLVING_FAILED,2,"exit code resolving failed","fill me"
EXIT_BINARY_NOT_FOUND,5,"binary not found","fill me"
EXIT_CONFIG_NOT_FOUND,6,"config not found","fill me"
# internal
EXIT_UPGRADE_FAILED,10,"upgrade failed","Will be returned when the database upgrade failed"
EXIT_UPGRADE_REQUIRED,11,"db upgrade required","Will be returned when a database upgrade is required"
EXIT_DOWNGRADE_REQUIRED,12,"db downgrade required","Will be returned when a database upgrade is required"
EXIT_VERSION_CHECK_FAILED,13,"version check failed","Will be returned when there is a version mismatch"
# startup
EXIT_ALREADY_RUNNING,20,"already running","Will be returned when arangod is already running according to PID-file"
EXIT_COULD_NOT_BIND_PORT,21,"port blocked","Will be returned when endpoint is taken by another process"
EXIT_COULD_NOT_LOCK,22,"could not lock - another process could be running","fill me"
# network
#EXIT_NO_COORDINATOR
#EXIT_NO_AGENCY
#EXIT_NO_CONNECTIVITY

170
lib/Basics/exitcodes.h Normal file
View File

@ -0,0 +1,170 @@
#ifndef TRIAGENS_BASICS_EXIT_CODES_H
#define TRIAGENS_BASICS_EXIT_CODES_H 1
////////////////////////////////////////////////////////////////////////////////
/// Exit codes and meanings
///
/// The following codes might be retured when exiting ArangoDB:
///
#include "Basics/error.h"
/// - 0: @LIT{success}
/// No error has occurred.
/// - 1: @LIT{exit with error}
/// Will be returned when a general error occurred.
/// - 2: @LIT{exit code resolving failed}
/// fill me
/// - 5: @LIT{binary not found}
/// fill me
/// - 6: @LIT{config not found}
/// fill me
/// - 10: @LIT{upgrade failed}
/// Will be returned when the database upgrade failed
/// - 11: @LIT{db upgrade required}
/// Will be returned when a database upgrade is required
/// - 12: @LIT{db downgrade required}
/// Will be returned when a database upgrade is required
/// - 13: @LIT{version check failed}
/// Will be returned when there is a version mismatch
/// - 20: @LIT{already running}
/// Will be returned when arangod is already running according to PID-file
/// - 21: @LIT{port blocked}
/// Will be returned when endpoint is taken by another process
/// - 22: @LIT{could not lock - another process could be running}
/// fill me
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief helper macro to define an exit code string
////////////////////////////////////////////////////////////////////////////////
#define REG_EXIT(id, label) TRI_set_exitno_string(TRI_ ## id, label);
////////////////////////////////////////////////////////////////////////////////
/// @brief register all exit codes for ArangoDB
////////////////////////////////////////////////////////////////////////////////
void TRI_InitializeExitMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 0: EXIT_SUCCESS
///
/// success
///
/// No error has occurred.
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_SUCCESS (0)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1: EXIT_FAILED
///
/// exit with error
///
/// Will be returned when a general error occurred.
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_FAILED (1)
////////////////////////////////////////////////////////////////////////////////
/// @brief 2: EXIT_CODE_RESOLVING_FAILED
///
/// exit code resolving failed
///
/// fill me
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_CODE_RESOLVING_FAILED (2)
////////////////////////////////////////////////////////////////////////////////
/// @brief 5: EXIT_BINARY_NOT_FOUND
///
/// binary not found
///
/// fill me
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_BINARY_NOT_FOUND (5)
////////////////////////////////////////////////////////////////////////////////
/// @brief 6: EXIT_CONFIG_NOT_FOUND
///
/// config not found
///
/// fill me
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_CONFIG_NOT_FOUND (6)
////////////////////////////////////////////////////////////////////////////////
/// @brief 10: EXIT_UPGRADE_FAILED
///
/// upgrade failed
///
/// Will be returned when the database upgrade failed
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_UPGRADE_FAILED (10)
////////////////////////////////////////////////////////////////////////////////
/// @brief 11: EXIT_UPGRADE_REQUIRED
///
/// db upgrade required
///
/// Will be returned when a database upgrade is required
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_UPGRADE_REQUIRED (11)
////////////////////////////////////////////////////////////////////////////////
/// @brief 12: EXIT_DOWNGRADE_REQUIRED
///
/// db downgrade required
///
/// Will be returned when a database upgrade is required
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_DOWNGRADE_REQUIRED (12)
////////////////////////////////////////////////////////////////////////////////
/// @brief 13: EXIT_VERSION_CHECK_FAILED
///
/// version check failed
///
/// Will be returned when there is a version mismatch
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_VERSION_CHECK_FAILED (13)
////////////////////////////////////////////////////////////////////////////////
/// @brief 20: EXIT_ALREADY_RUNNING
///
/// already running
///
/// Will be returned when arangod is already running according to PID-file
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_ALREADY_RUNNING (20)
////////////////////////////////////////////////////////////////////////////////
/// @brief 21: EXIT_COULD_NOT_BIND_PORT
///
/// port blocked
///
/// Will be returned when endpoint is taken by another process
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_COULD_NOT_BIND_PORT (21)
////////////////////////////////////////////////////////////////////////////////
/// @brief 22: EXIT_COULD_NOT_LOCK
///
/// could not lock - another process could be running
///
/// fill me
////////////////////////////////////////////////////////////////////////////////
#define TRI_EXIT_COULD_NOT_LOCK (22)
#endif

View File

@ -171,6 +171,7 @@ add_library(${LIB_ARANGO} STATIC
Basics/tri-zip.cpp
Basics/vector.cpp
Basics/voc-errors.cpp
Basics/exitcodes.cpp
Basics/voc-mimetypes.cpp
Basics/xxhash.cpp
Endpoint/Endpoint.cpp

1
utils/generateErrorfile.py Normal file → Executable file
View File

@ -1,3 +1,4 @@
#!/usr/bin/python
import csv, sys, os.path, re
# wrap text after x characters

227
utils/generateExitCodesFiles.py Executable file
View File

@ -0,0 +1,227 @@
#!/usr/bin/python
import csv, sys, os.path, re
# wrap text after x characters
def wrap(string, width=80, ind1=0, ind2=0, prefix=''):
string = prefix + ind1 * " " + string
newstring = ""
string = string.replace("\n", " ")
while len(string) > width:
marker = width - 1
while not string[marker].isspace():
marker = marker - 1
newline = string[0:marker] + "\n"
newstring = newstring + newline
string = prefix + ind2 * " " + string[marker + 1:]
return newstring + string
# generate javascript file from errors
def genJsFile(errors):
jslint = "/*jshint maxlen: 240 */\n/*global require */\n\n"
out = jslint \
+ prologue\
+ "(function () {\n"\
+ " \"use strict\";\n"\
+ " var internal = require(\"internal\");\n"\
+ "\n"\
+ " internal.exitCodes = {\n"
# print individual errors
i = 0
for e in errors:
name = "\"" + e[0] + "\""
msg = e[2].replace("\n", " ").replace("\\", "").replace("\"", "\\\"")
out = out\
+ " " + name.ljust(30) + " : { \"code\" : " + e[1] + ", \"message\" : \"" + msg + "\" }"
i = i + 1
if i < len(errors):
out = out + ",\n"
else:
out = out + "\n"
out = out\
+ " };\n"\
+ "}());\n"\
+ "\n"
return out
# generate NSIS implementation file from errors
def genNSISFile(errors, filename):
impl = """
!include "LogicLib.nsh"
!macro printExitCode exitCode Message
Push "${exitCode}"
Push "${Message}"
Call printExitCode
!macroend
Function printExitCode
pop $1
pop $2
${Switch} $0\n
"""
# print individual errors
for e in errors:
impl += """
${Case} %s # %s
MessageBox MB_ICONEXCLAMATION '$1:$\\r$\\n%s'
; %s
${Break}
""" % (
e[1],
e[0],
e[2],
e[3]
)
impl = impl + """
${EndSwitch}
FunctionEnd
"""
return impl.replace("\r", "\r\n")
# generate C implementation file from errors
def genCFile(errors, filename):
headerfile = os.path.splitext(filename)[0] + ".h"
impl = prologue\
+ "#include \"Basics/Common.h\"\n"\
+ "#include \"" + headerfile + "\"\n"\
+ "\n"\
+ "void TRI_InitializeExitMessages () {\n"
# print individual errors
for e in errors:
msg = e[2].replace("\n", " ").replace("\\", "").replace("\"", "\\\"")
impl = impl\
+ " REG_EXIT(" + e[0] + ", \"" + msg + "\");\n"
impl = impl\
+ "}\n"
return impl
# generate C header file from errors
def genCHeaderFile(errors):
wiki = "////////////////////////////////////////////////////////////////////////////////\n"\
+ "/// Exit codes and meanings\n"\
+ "///\n"\
+ "/// The following codes might be retured when exiting ArangoDB:\n"\
+ "///\n"\
+ "#include \"Basics/error.h\"\n"
for e in errors:
wiki = wiki\
+ "/// - " + e[1] + ": @LIT{" + e[2].replace("%", "\%").replace("<", "\<").replace(">", "\>") + "}\n"\
+ wrap(e[3], 80, 0, 0, "/// ") + "\n"
wiki = wiki\
+ "////////////////////////////////////////////////////////////////////////////////\n"
header = "\n"\
+ "#ifndef TRIAGENS_BASICS_EXIT_CODES_H\n"\
+ "#define TRIAGENS_BASICS_EXIT_CODES_H 1\n"\
+ "\n"\
+ wiki\
+ "\n"\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "/// @brief helper macro to define an exit code string\n"\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "\n"\
+ "#define REG_EXIT(id, label) TRI_set_exitno_string(TRI_ ## id, label);\n"\
+ "\n"\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "/// @brief register all exit codes for ArangoDB\n"\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "\n"\
+ "void TRI_InitializeExitMessages ();\n"\
+ "\n"
# print individual errors
for e in errors:
header = header\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "/// @brief " + e[1] + ": " + e[0] + "\n"\
+ "///\n"\
+ wrap(e[2], 80, 0, 0, "/// ").replace("<", "\<").replace(">", "\>") + "\n"\
+ "///\n"\
+ wrap(e[3], 80, 0, 0, "/// ") + "\n"\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "\n"\
+ "#define TRI_" + e[0].ljust(61) + " (" + e[1] + ")\n"\
+ "\n"
header = header\
+ "#endif\n"\
+ "\n"
return header
# define some globals
prologue = "////////////////////////////////////////////////////////////////////////////////\n"\
+ "/// @brief auto-generated file generated from exitcodes.dat\n"\
+ "////////////////////////////////////////////////////////////////////////////////\n"\
+ "\n"
if len(sys.argv) < 3:
print >> sys.stderr, "usage: %s <sourcefile> <outfile>" % sys.argv[0]
sys.exit()
source = sys.argv[1]
# read input file
errors = csv.reader(open(source, "rb"))
errorsList = []
r1 = re.compile(r'^#.*')
for e in errors:
if len(e) == 0:
continue
if r1.match(e[0]):
continue
if e[0] == "" or e[1] == "" or e[2] == "" or e[3] == "":
print >> sys.stderr, "invalid exit code declaration file: %s" % (source)
sys.exit()
errorsList.append(e)
outfile = sys.argv[2]
extension = os.path.splitext(outfile)[1]
filename = outfile
if extension == ".tmp":
filename = os.path.splitext(outfile)[0]
extension = os.path.splitext(filename)[1]
if extension == ".js":
out = genJsFile(errorsList)
elif extension == ".h":
out = genCHeaderFile(errorsList)
elif extension == ".cpp":
out = genCFile(errorsList, filename)
elif extension == ".nsh":
out = genNSISFile(errorsList, filename)
else:
print >> sys.stderr, "usage: %s <sourcefile> <outfile>" % sys.argv[0]
sys.exit()
outFile = open(outfile, "wb")
outFile.write(out);
outFile.close()