Skip to content

Commit dad1eb5

Browse files
Mikael Knutssonsathieu
Mikael Knutsson
authored andcommitted
Improving deb packaging with init scripts and user creation
1 parent b1f318d commit dad1eb5

12 files changed

+410
-10
lines changed

CHANGES.txt

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ Backwards Incompatibilities
88

99
* Using stftime literals for filenames during rotation in FileOutput plugin (#1469).
1010

11+
* The package created by 'make deb' creates an "heka" user and ships an init script
12+
and a systemd unit.
13+
14+
* The 'make deb' target requires fakeroot and debhelper to be installed.
15+
1116
Features
1217
--------
1318

CMakeLists.txt

+17-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(CPACK_PACKAGE_VERSION_PATCH 0)
1111
set(CPACK_PACKAGE_VENDOR "Mozilla")
1212
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
1313
set(CPACK_PACKAGE_CONTACT "[email protected]")
14+
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
1415

1516
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
1617

@@ -96,7 +97,6 @@ elseif(UNIX)
9697
endif()
9798

9899
include(CTest)
99-
include(CPack)
100100
include(externals)
101101
include(mocks)
102102

@@ -226,21 +226,27 @@ add_custom_target(sbmgrload ALL
226226
${GO_EXECUTABLE} install ${LDFLAGS} github.com/mozilla-services/heka/cmd/heka-sbmgrload
227227
DEPENDS hekad)
228228

229+
## DEBIAN SPECIFIC THINGS HERE
230+
set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_SOURCE_DIR}/CPackConfig.cmake")
229231
if (UNIX AND DPKG_EXECUTABLE)
230-
execute_process(COMMAND "${DPKG_EXECUTABLE}" --print-architecture
231-
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
232-
OUTPUT_STRIP_TRAILING_WHITESPACE)
233-
234-
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.14)")
235232
get_filename_component(CMAKE_BIN_DIR ${CMAKE_COMMAND} PATH)
236233
set(CPACK_COMMAND ${CMAKE_BIN_DIR}/cpack)
237234

235+
execute_process(COMMAND "${DPKG_EXECUTABLE}" --print-architecture
236+
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
237+
238238
add_custom_target(deb
239-
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool..."
240-
COMMAND ${CPACK_COMMAND} -G DEB -D CPACK_PACKAGE_FILE_NAME="${CMAKE_PROJECT_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" --config ./CPackConfig.cmake
241-
DEPENDS hekad
242-
COMMENT "Custom deb target")
239+
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --switch="$(COLOR)" --cyan "Run CPack packaging tool..."
240+
COMMAND ${CPACK_COMMAND} -G DEB
241+
DEPENDS hekad
242+
COMMENT "Custom deb target")
243+
244+
add_subdirectory(debian)
243245
endif()
246+
247+
# MOVING INCLUSION OF CPACK DOWN HERE SO IT ACTUALLY GETS THE VARIABLES WE SET
248+
include(CPack)
249+
244250
add_test(cmd/hekad ${GO_EXECUTABLE} test ${LDFLAGS} ${BENCHMARK_FLAG} github.com/mozilla-services/heka/cmd/hekad)
245251
add_test(message ${GO_EXECUTABLE} test ${LDFLAGS} ${BENCHMARK_FLAG} github.com/mozilla-services/heka/message)
246252
add_test(pipeline ${GO_EXECUTABLE} test ${LDFLAGS} ${BENCHMARK_FLAG} github.com/mozilla-services/heka/pipeline)
@@ -281,6 +287,7 @@ endif()
281287
install(FILES "${CMAKE_SOURCE_DIR}/LICENSE.txt" DESTINATION "share/${CMAKE_PROJECT_NAME}")
282288
install(DIRECTORY "${CMAKE_SOURCE_DIR}/dasher" DESTINATION "share/${CMAKE_PROJECT_NAME}")
283289
install(DIRECTORY "${PROJECT_PATH}/lib/luasandbox/modules/" DESTINATION "share/${CMAKE_PROJECT_NAME}/lua_modules")
290+
install(DIRECTORY "${CMAKE_SOURCE_DIR}/examples/conf/" DESTINATION "share/${CMAKE_PROJECT_NAME}/examples")
284291
install(DIRECTORY "${CMAKE_SOURCE_DIR}/sandbox/lua/modules/" DESTINATION "share/${CMAKE_PROJECT_NAME}/lua_modules")
285292
install(DIRECTORY "${CMAKE_SOURCE_DIR}/sandbox/lua/decoders/" DESTINATION "share/${CMAKE_PROJECT_NAME}/lua_decoders")
286293
install(DIRECTORY "${CMAKE_SOURCE_DIR}/sandbox/lua/filters/" DESTINATION "share/${CMAKE_PROJECT_NAME}/lua_filters")

CPackConfig.cmake

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# See http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#Overall_usage_.28common_to_all_generators.29
2+
3+
if(CPACK_GENERATOR MATCHES "DEB")
4+
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
5+
# When the DEB-generator runs, we want him to run our install-script
6+
set(CPACK_INSTALL_SCRIPT ${CPACK_DEBIAN_INSTALL_SCRIPT})
7+
endif()

cmake/CMakeDebHelper.cmake

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#=============================================================================
2+
# CMakeDebHelper, Copyright (C) 2013 Sebastian Kienzl
3+
# http://knzl.de/cmake-debhelper/
4+
# Licensed under the GPL v2, see LICENSE
5+
#=============================================================================
6+
7+
# configure() .in-files to the CURRENT_BINARY_DIR
8+
foreach( _F ${DH_INPUT} )
9+
# strip the .in part
10+
string( REGEX REPLACE ".in$" "" _F_WE ${_F} )
11+
configure_file( ${_F} ${_F_WE} @ONLY )
12+
endforeach()
13+
14+
# compat and control is only needed for running the debhelpers,
15+
# CMake is going to make up the one that ends up in the deb.
16+
file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/compat "9" )
17+
if( NOT CPACK_DEBIAN_PACKAGE_NAME )
18+
string( TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME )
19+
endif()
20+
file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/control "Package: ${CPACK_DEBIAN_PACKAGE_NAME}\nArchitecture: any\n" )
21+
22+
# Some debhelpers need fakeroot, we use it for all of them
23+
find_program( FAKEROOT fakeroot )
24+
if( NOT FAKEROOT )
25+
message( SEND_ERROR "fakeroot not found, please install" )
26+
endif()
27+
28+
find_program( DEBHELPER dh_prep )
29+
if( NOT DEBHELPER )
30+
message( SEND_ERROR "debhelper not found, please install" )
31+
endif()
32+
33+
# Compose a string with a semicolon-seperated list of debhelpers
34+
foreach( _DH ${DH_RUN} )
35+
set( _DH_RUN_SC_LIST "${_DH_RUN_SC_LIST} ${_DH} ;" )
36+
endforeach()
37+
38+
# Making sure the debhelpers run each time we change one of ${DH_INPUT}
39+
add_custom_command(
40+
OUTPUT dhtimestamp
41+
42+
# dh_prep is needed to clean up, dh_* aren't idempotent
43+
COMMAND ${FAKEROOT} dh_prep
44+
45+
# I haven't found another way to run a list of commands here
46+
COMMAND ${FAKEROOT} -- sh -c "${_DH_RUN_SC_LIST}"
47+
48+
# needed to create the files we'll use
49+
COMMAND ${FAKEROOT} dh_installdeb
50+
51+
COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/dhtimestamp
52+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
53+
DEPENDS ${DH_INPUT}
54+
COMMENT "Running debhelpers"
55+
VERBATIM
56+
)
57+
58+
add_custom_target( dhtarget ALL
59+
DEPENDS dhtimestamp
60+
)
61+
62+
# these files are generated by debhelpers from our templates
63+
foreach( _F ${DH_GENERATED_CONTROL_EXTRA} )
64+
set( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
65+
${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}
66+
${CMAKE_CURRENT_BINARY_DIR}/${CPACK_DEBIAN_PACKAGE_NAME}/DEBIAN/${_F}
67+
CACHE INTERNAL ""
68+
)
69+
endforeach()
70+
71+
# This will copy the generated dhhelper-files to our to-be-cpacked-directory.
72+
# CPACK_INSTALL_SCRIPT must be set to the value of CPACK_DEBIAN_INSTALL_SCRIPT in the file
73+
# pointed to by CPACK_PROJECT_CONFIG_FILE.
74+
set( CPACK_DEBIAN_INSTALL_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/CMakeDebHelperInstall.cmake CACHE INTERNAL "" )

cmake/CMakeDebHelperInstall.cmake

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# This script is used internally by CMakeDebHelper.
2+
# It is run at CPack-Time and copies the files generated by the debhelpers to the right place.
3+
4+
if( NOT CPACK_DEBIAN_PACKAGE_NAME )
5+
string( TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME )
6+
endif()
7+
8+
# Copy all generated files where the packing will happen,
9+
# exclude the DEBIAN-directory.
10+
file( COPY
11+
"${CPACK_OUTPUT_FILE_PREFIX}/debian/${CPACK_DEBIAN_PACKAGE_NAME}/"
12+
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}"
13+
PATTERN DEBIAN EXCLUDE
14+
)

debian/CMakeLists.txt

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Files that should be configured and will be used by the debhelpers as input.
2+
# In these files you can use @CMAKE_VARIABLES@ that will be filled out.
3+
# We don't glob here because then CMake won't regenerate automatically when a file is added.
4+
#
5+
# Note that CPACK_PACKAGE_NAME is assumed to be lower-case at this point.
6+
# If it isn't, you should lowercase it here (string( TOLOWER ...)) and the filenames,
7+
# because that's how Debian wants it.
8+
# (Alternatively, set and use a lowercase CPACK_DEBIAN_PACKAGE_NAME)
9+
set(DH_INPUT
10+
${CPACK_PACKAGE_NAME}.init.in
11+
${CPACK_PACKAGE_NAME}.service.in
12+
${CPACK_PACKAGE_NAME}.preinst.in
13+
${CPACK_PACKAGE_NAME}.postinst.in
14+
${CPACK_PACKAGE_NAME}.postrm.in
15+
)
16+
17+
# These files (generated by dhelpers) will be copied into the control-part of the deb.
18+
# Files that end up in the filesystem normally (e.g. cron/init-scripts) must not be mentioned here.
19+
# It's a good idea to add "conffiles", as the debhelpers may generate it.
20+
set(DH_GENERATED_CONTROL_EXTRA
21+
preinst
22+
postinst
23+
postrm
24+
prerm
25+
conffiles
26+
)
27+
28+
# Set this to the debhelpers that should run,
29+
# dh_prep and dh_installdeb need not be listed here.
30+
set(DH_RUN
31+
dh_installcron
32+
dh_installinit
33+
)
34+
35+
# At this point, CMakeDebHelper must be included (add .cmake if you have it in this directory)
36+
37+
include(CMakeDebHelper)
38+
39+
# CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA and CPACK_INSTALL_SCRIPT are set now, don't modify them!
40+
41+
42+
# These must be set in the PARENT_SCOPE, as this is where we'll include CPack
43+
# See http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29
44+
45+
set(CPACK_GENERATOR ${CPACK_GENERATOR} "DEB" PARENT_SCOPE)
46+
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON PARENT_SCOPE)

debian/heka.init.in

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#! /bin/sh
2+
### BEGIN INIT INFO
3+
# Provides: heka
4+
# Required-Start: $remote_fs $syslog
5+
# Required-Stop: $remote_fs $syslog
6+
# Default-Start: 2 3 4 5
7+
# Default-Stop: 0 1 6
8+
# Short-Description: heka - data collector and processor daemon
9+
# Description: heka - data collector and processor daemon
10+
### END INIT INFO
11+
12+
PATH=/sbin:/usr/sbin:/bin:/usr/bin
13+
DESC=hekad
14+
NAME=hekad
15+
DAEMON=/usr/bin/$NAME
16+
DAEMON_USER=heka
17+
DAEMON_ARGS="-config=/etc/heka/conf.d/"
18+
PIDFILE=/var/run/$NAME.pid
19+
LOGFILE=/var/log/$NAME.log
20+
SCRIPTNAME=/etc/init.d/heka
21+
22+
# Exit if the package is not installed
23+
[ -x "$DAEMON" ] || exit 0
24+
25+
# Read configuration variable file if it is present
26+
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
27+
28+
# Load the VERBOSE setting and other rcS variables
29+
. /lib/init/vars.sh
30+
31+
# Define LSB log_* functions.
32+
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
33+
# and status_of_proc is working.
34+
. /lib/lsb/init-functions
35+
36+
#
37+
# Function that starts the daemon/service
38+
#
39+
do_start()
40+
{
41+
# Return
42+
# 0 if daemon has been started
43+
# 1 if daemon was already running
44+
# 2 if daemon could not be started
45+
pid=$(pidofproc -p $PIDFILE "$NAME")
46+
if [ -n "$pid" ] ; then
47+
log_daemon_msg "$desc is already running (PID `cat ${PIDFILE}`)"
48+
return 1
49+
fi
50+
start-stop-daemon --start --quiet --chuid $DAEMON_USER --make-pidfile --background --pidfile $PIDFILE \
51+
--no-close --exec $DAEMON -- $DAEMON_ARGS >> $LOGFILE 2>&1 \
52+
|| return 2
53+
# Add code here, if necessary, that waits for the process to be ready
54+
# to handle requests from services started subsequently which depend
55+
# on this one. As a last resort, sleep for some time.
56+
}
57+
58+
#
59+
# Function that stops the daemon/service
60+
#
61+
do_stop()
62+
{
63+
# Return
64+
# 0 if daemon has been stopped
65+
# 1 if daemon was already stopped
66+
# 2 if daemon could not be stopped
67+
# other if a failure occurred
68+
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
69+
RETVAL="$?"
70+
[ "$RETVAL" = 2 ] && return 2
71+
# Wait for children to finish too if this is a daemon that forks
72+
# and if the daemon is only ever run from this initscript.
73+
# If the above conditions are not satisfied then add some other code
74+
# that waits for the process to drop all resources that could be
75+
# needed by services started subsequently. A last resort is to
76+
# sleep for some time.
77+
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
78+
[ "$?" = 2 ] && return 2
79+
# Many daemons don't delete their pidfiles when they exit.
80+
rm -f $PIDFILE
81+
return "$RETVAL"
82+
}
83+
84+
#
85+
# Function that sends a SIGHUP to the daemon/service
86+
#
87+
do_reload() {
88+
#
89+
# If the daemon can reload its configuration without
90+
# restarting (for example, when it is sent a SIGHUP),
91+
# then implement that here.
92+
#
93+
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
94+
return 0
95+
}
96+
97+
case "$1" in
98+
start)
99+
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
100+
do_start
101+
case "$?" in
102+
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
103+
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
104+
esac
105+
;;
106+
stop)
107+
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
108+
do_stop
109+
case "$?" in
110+
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
111+
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
112+
esac
113+
;;
114+
status)
115+
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
116+
;;
117+
reload|force-reload)
118+
log_daemon_msg "Reloading $DESC" "$NAME"
119+
do_reload
120+
log_end_msg $?
121+
;;
122+
restart|force-reload)
123+
#
124+
# If the "reload" option is implemented then remove the
125+
# 'force-reload' alias
126+
#
127+
log_daemon_msg "Restarting $DESC" "$NAME"
128+
do_stop
129+
case "$?" in
130+
0|1)
131+
do_start
132+
case "$?" in
133+
0) log_end_msg 0 ;;
134+
1) log_end_msg 1 ;; # Old process is still running
135+
*) log_end_msg 1 ;; # Failed to start
136+
esac
137+
;;
138+
*)
139+
# Failed to stop
140+
log_end_msg 1
141+
;;
142+
esac
143+
;;
144+
*)
145+
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
146+
exit 3
147+
;;
148+
esac
149+
150+
:

debian/heka.postinst.in

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#! /bin/sh
2+
3+
set -eu
4+
USER="heka"
5+
GROUP="$USER"
6+
7+
if [ ! -d /etc/heka/conf.d/ ]
8+
then
9+
mkdir -p /etc/heka/conf.d/
10+
cp /usr/share/heka/examples/hekad.toml /etc/heka/conf.d/00-hekad.toml
11+
fi
12+
13+
if [ ! -d /usr/share/doc/heka/ ]
14+
then
15+
mkdir -p /usr/share/doc/heka
16+
ln -s /usr/share/heka/examples /usr/share/doc/heka/examples
17+
fi
18+
19+
#DEBHELPER#

0 commit comments

Comments
 (0)