Skip to content

Commit

Permalink
systemd instancing support & rpm build improvements
Browse files Browse the repository at this point in the history
The major things this does are adding systemd support to the rpm .spec
file, and adding systemd instancing support. This means that it is
possible to run multiple memcached instances without having to do
any additional configuration or hack on init scripts.

To use:
    systemctl start memcached@11211 memcached@11311 memcached@11411

sysconfig files at /etc/sysconfig/memcached.<port> will be read as
appropriate, to allow differing configurations per-port. Defaults
will be read from /etc/sysconfig/memcached before the port-specific
settings are read.

You can also still start memcached the standard way just by doing
"systemctl start memcached". This will read /etc/sysconfig/memcached
and nothing else.

The "enhanced security" lines in the systemd unit file will be commented
out on systems where we know systemd isn't knew enough (fedora < 26 and
Redhat/CentOS 7), and enabled on other systems.

There are two versions of the .service file included, one for standard
memcached invocations and one for instanced invocations. The two are
very similar, but not identical. Ideally, we'd only have one version
in the source tree and we'd massage it with sed or somesuch during the
rpm build, but couldn't think of a super clean way to do that, so erred
on the side of simplicity.

A decent amount of spec file work was needed to enable this functionality.
In the process, I also cleaned up several additional aspects of the spec
file (like using %{name} in places where it was appropriate). I also
commented out the automatic restart in the %postun section, for two main
reasons:
    1. The try-restart for instanced memcached will produce an error if
    instanced memcached isn't in use, which is probably quite confusing to
    people who aren't using that functionality and are just trying to update
    their package. (There's workarounds for this, but I try to keep pre/post
    scripts as simple as humanly possible)

    2. Automatic restarts on updates means the cache gets flushed, which
    means you can no longer safely use large-scale management tools (like
    puppet or chef) to roll out new versions, at least not without a lot
    of planning first. Not automatically dumping someone's caches feels
    safer, here.
  • Loading branch information
elfchief authored and dormando committed Feb 20, 2018
1 parent 4f3d6d6 commit 7141922
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 60 deletions.
126 changes: 100 additions & 26 deletions memcached.spec.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# Set with_systemd on distros that use it, so we can install the service
# file, otherwise the sysvinit script will be installed
%if 0%{?fedora} >= 14 || 0%{?rhel} >= 7 || 0%{?suse_version} >= 1210
%global with_systemd 1
BuildRequires: systemd-units

# Disable some systemd safety features on OSes without a new enough systemd
# (new enough is systemd >= 233)
%if 0%{?fedora} < 26 || 0%{?rhel} > 0
%global safer_systemd 0
%else
%global safer_systemd 1
%endif

%else
%global with_systemd 0
%endif

Name: memcached
Version: @VERSION@
Release: @RELEASE@%{?dist}
Expand All @@ -6,78 +24,124 @@ Summary: High Performance, Distributed Memory Object Cache
Group: System Environment/Daemons
License: BSD
URL: http://memcached.org
Source0: http://memcached.org/files/%{name}-@[email protected]
Source0: http://memcached.org/files/%{name}-%{version}.tar.gz
Source1: memcached.sysconfig
Source2: memcached.service
Source3: [email protected]
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

BuildRequires: libevent-devel
BuildRequires: perl(Test::More)
BuildRequires: /usr/bin/prove
Requires: initscripts
%if %{with_systemd}
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
%else
Requires(post): /sbin/chkconfig
Requires(preun): /sbin/chkconfig, /sbin/service
Requires(postun): /sbin/service
%endif

%description
memcached is a high-performance, distributed memory object caching
system, generic in nature, but intended for use in speeding up dynamic
web applications by alleviating database load.

%prep
%setup -q -n %{name}-@FULLVERSION@
%setup -q -n %{name}-%{version}


%build
%configure

make %{?_smp_mflags}


%check
make test


%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}

# remove memcached-debug
rm -f %{buildroot}/%{_bindir}/memcached-debug
rm -f %{buildroot}/%{_bindir}/%{name}-debug

# Perl script for monitoring memcached
install -Dp -m0755 scripts/memcached-tool %{buildroot}%{_bindir}/memcached-tool
install -Dp -m0755 scripts/memcached-tool %{buildroot}%{_bindir}/%{name}-tool

# Init script
install -Dp -m0755 scripts/memcached.sysv %{buildroot}%{_initrddir}/memcached
%if %{with_systemd}
install -Dp -m0755 scripts/memcached.service %{buildroot}%{_unitdir}/%{name}.service
install -Dp -m0755 scripts/[email protected] %{buildroot}%{_unitdir}/%{name}@.service

if [ %{safer_systemd} -gt 0 ]; then
sed -e -i 's/^##safer##//g' %{buildroot}%{_unitdir}/%{name}.service %{buildroot}%{_unitdir}/%{name}@.service
else
sed -e -i 's/^##safer##/#/g' %{buildroot}%{_unitdir}/%{name}.service %{buildroot}%{_unitdir}/%{name}@.service
fi
%else
install -Dp -m0755 scripts/memcached.sysv %{buildroot}%{_initrddir}/%{name}
%endif

# Default configs
mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig
cat <<EOF >%{buildroot}/%{_sysconfdir}/sysconfig/%{name}
PORT="11211"
USER="nobody"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
EOF
install -Dp -m0644 scripts/memcached.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/%{name}

# pid directory
mkdir -p %{buildroot}/%{_localstatedir}/run/memcached
mkdir -p %{buildroot}/%{_localstatedir}/run/%{name}


%clean
rm -rf %{buildroot}


%post
/sbin/chkconfig --add %{name}
if [ $1 -eq 1 ]; then
# Initial install
%if %{with_systemd}
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
%else
/sbin/chkconfig --add %{name}
%endif
fi


%preun
if [ "$1" = 0 ] ; then
/sbin/service %{name} stop > /dev/null 2>&1
# Removal, not upgrade
%if %{with_systemd}
/bin/systemctl --no-reload disable %{name}.service > /dev/null 2>&1 || :
/bin/systemctl --no-reload disable %{name}@\*.service > /dev/null 2>&1 || :
/bin/systemctl stop %{name}.service > /dev/null 2>&1 || :
/bin/systemctl stop %{name}@\*.service > /dev/null 2>&1 || :
%else
/sbin/service %{name} stop > /dev/null 2&>1 || :
/sbin/chkconfig --del %{name}
%endif
fi

exit 0


%postun
if [ "$1" -ge 1 ]; then
/sbin/service %{name} condrestart > /dev/null 2>&1
fi
%if %{with_systemd}
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
%endif

# Don't auto-restart memcached on upgrade -- let user control when cache flushes
# if [ "$1" -ge 1 ]; then
# # upgrade, not install
# %if %{with_systemd}
# /bin/systemctl try-restart %{name}.service
# /bin/systemctl try-restart %{name}@\*.service
# %else
# /sbin/service %named condrestart 2>/dev/null || :
# %endif
#fi

exit 0


Expand All @@ -86,14 +150,24 @@ exit 0
%doc AUTHORS ChangeLog COPYING NEWS README.md doc/CONTRIBUTORS doc/*.txt
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}

%dir %attr(750,nobody,nobody) %{_localstatedir}/run/memcached
%{_bindir}/memcached-tool
%{_bindir}/memcached
%{_mandir}/man1/memcached.1*
%{_initrddir}/memcached
%{_includedir}/memcached
%dir %attr(750,nobody,nobody) %{_localstatedir}/run/%{name}
%{_bindir}/%{name}-tool
%{_bindir}/%{name}
%{_mandir}/man1/%{name}.1*
%{_includedir}/%{name}

%if %{with_systemd}
%{_unitdir}/%{name}.service
%{_unitdir}/%{name}@.service
%else
%{_initrddir}/%{name}
%endif

%changelog
* Wed Jul 5 2017 J. Grizzard <[email protected]> - 1.4.39
- Add systemd-aware build
- Add both static and instanced versions of memcached unit files

* Mon Nov 2 2009 Dormando <[email protected]> - 1.4.3-1
- Fix autogen more.

Expand All @@ -113,7 +187,7 @@ exit 0
- above suggestions from Bernard Johnson

* Mon May 7 2007 Paul Lindner <[email protected]> - 1.2.2-2
- Tidiness improvements suggested by Ruben Kerkhof in bugzilla #238994
- Tidyness improvements suggested by Ruben Kerkhof in bugzilla #238994

* Fri May 4 2007 Paul Lindner <[email protected]> - 1.2.2-1
- Initial spec file created via rpmdev-newspec
80 changes: 46 additions & 34 deletions scripts/memcached.service
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# It's not recommended to modify this file in-place, because it will be
# overwritten during upgrades. If you want to customize, the best
# way is to use the "systemctl edit" command to create an override unit.

#
# For example, to pass additional options, create an override unit
# (as is done by systemctl edit) and enter the following:

#
# [Service]
# Environment=OPTIONS="-l 127.0.0.1,::1"

Expand All @@ -17,56 +17,68 @@ After=network.target
EnvironmentFile=/etc/sysconfig/memcached
ExecStart=/usr/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS

# Set up a new file system namespace and mounts private /tmp and /var/tmp directories
# so this service cannot access the global directories and other processes cannot
# access this service's directories.
# Set up a new file system namespace and mounts private /tmp and /var/tmp
# directories so this service cannot access the global directories and
# other processes cannot access this service's directories.
PrivateTmp=true

# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by this unit.
# Mounts the /usr, /boot, and /etc directories read-only for processes
# invoked by this unit.
ProtectSystem=full

# Ensures that the service process and all its children can never gain new privileges
# Ensures that the service process and all its children can never gain new
# privileges
NoNewPrivileges=true

# Sets up a new /dev namespace for the executed processes and only adds API pseudo devices
# such as /dev/null, /dev/zero or /dev/random (as well as the pseudo TTY subsystem) to it,
# but no physical devices such as /dev/sda.
# Sets up a new /dev namespace for the executed processes and only adds API
# pseudo devices such as /dev/null, /dev/zero or /dev/random (as well as
# the pseudo TTY subsystem) to it, but no physical devices such as /dev/sda.
PrivateDevices=true

# Required for dropping privileges and running as a different user
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE

# Attempts to create memory mappings that are writable and executable at the same time,
# or to change existing memory mappings to become executable are prohibited.
MemoryDenyWriteExecute=true
# Restricts the set of socket address families accessible to the processes
# of this unit. Protects against vulnerabilities such as CVE-2016-8655
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

# Explicit module loading will be denied. This allows to turn off module load and unload
# operations on modular kernels. It is recommended to turn this on for most services that
# do not need special file systems or extra kernel modules to work.
ProtectKernelModules=true

# Kernel variables accessible through /proc/sys, /sys, /proc/sysrq-trigger, /proc/latency_stats,
# /proc/acpi, /proc/timer_stats, /proc/fs and /proc/irq will be made read-only to all processes
# of the unit. Usually, tunable kernel variables should only be written at boot-time, with the
# sysctl.d(5) mechanism. Almost no services need to write to these at runtime; it is hence
# recommended to turn this on for most services.
ProtectKernelTunables=true
# Some security features are not in the older versions of systemd used by
# e.g. RHEL7/CentOS 7. The below settings are automatically edited at package
# build time to uncomment them if the target platform supports them.

# The Linux Control Groups (cgroups(7)) hierarchies accessible through /sys/fs/cgroup will be
# made read-only to all processes of the unit. Except for container managers no services should
# require write access to the control groups hierarchies; it is hence recommended to turn this on
# for most services
ProtectControlGroups=true
# Attempts to create memory mappings that are writable and executable at
# the same time, or to change existing memory mappings to become executable
# are prohibited.
##safer##MemoryDenyWriteExecute=true

# Any attempts to enable realtime scheduling in a process of the unit are refused.
RestrictRealtime=true
# Explicit module loading will be denied. This allows to turn off module
# load and unload operations on modular kernels. It is recommended to turn
# this on for most services that do not need special file systems or extra
# kernel modules to work.
##safer##ProtectKernelModules=true

# Restricts the set of socket address families accessible to the processes of this unit.
# Protects against vulnerabilities such as CVE-2016-8655
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
# Kernel variables accessible through /proc/sys, /sys, /proc/sysrq-trigger,
# /proc/latency_stats, /proc/acpi, /proc/timer_stats, /proc/fs and /proc/irq
# will be made read-only to all processes of the unit. Usually, tunable
# kernel variables should only be written at boot-time, with the sysctl.d(5)
# mechanism. Almost no services need to write to these at runtime; it is hence
# recommended to turn this on for most services.
##safer##ProtectKernelTunables=true

# The Linux Control Groups (cgroups(7)) hierarchies accessible through
# /sys/fs/cgroup will be made read-only to all processes of the unit.
# Except for container managers no services should require write access
# to the control groups hierarchies; it is hence recommended to turn this
# on for most services
##safer##ProtectControlGroups=true

# Any attempts to enable realtime scheduling in a process of the unit are
# refused.
##safer##RestrictRealtime=true

# Takes away the ability to create or manage any kind of namespace
RestrictNamespaces=true
##safer##RestrictNamespaces=true

[Install]
WantedBy=multi-user.target
10 changes: 10 additions & 0 deletions scripts/memcached.sysconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# These defaults will be used by every memcached instance, unless overridden
# by values in /etc/sysconfig/memcached.<port>
USER="nobody"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""

# The PORT variable will only be used by memcached.service, not by
# memcached@xxxxx services, which will use the xxxxx
PORT="11211"
Loading

0 comments on commit 7141922

Please sign in to comment.