1%global _sbindir    /sbin
2%global _libdir     /%{_lib}
3
4# Set the default udev directory based on distribution.
5%if %{undefined _udevdir}
6%if 0%{?fedora}%{?rhel}%{?centos}%{?openEuler}
7%global _udevdir    %{_prefix}/lib/udev
8%else
9%global _udevdir    /lib/udev
10%endif
11%endif
12
13# Set the default udevrule directory based on distribution.
14%if %{undefined _udevruledir}
15%if 0%{?fedora}%{?rhel}%{?centos}%{?openEuler}
16%global _udevruledir    %{_prefix}/lib/udev/rules.d
17%else
18%global _udevruledir    /lib/udev/rules.d
19%endif
20%endif
21
22# Set the default dracut directory based on distribution.
23%if %{undefined _dracutdir}
24%if 0%{?fedora}%{?rhel}%{?centos}%{?openEuler}
25%global _dracutdir  %{_prefix}/lib/dracut
26%else
27%global _dracutdir  %{_prefix}/share/dracut
28%endif
29%endif
30
31%if %{undefined _initconfdir}
32%global _initconfdir /etc/sysconfig
33%endif
34
35%if %{undefined _unitdir}
36%global _unitdir %{_prefix}/lib/systemd/system
37%endif
38
39%if %{undefined _presetdir}
40%global _presetdir %{_prefix}/lib/systemd/system-preset
41%endif
42
43%if %{undefined _modulesloaddir}
44%global _modulesloaddir %{_prefix}/lib/modules-load.d
45%endif
46
47%if %{undefined _systemdgeneratordir}
48%global _systemdgeneratordir %{_prefix}/lib/systemd/system-generators
49%endif
50
51%if %{undefined _pkgconfigdir}
52%global _pkgconfigdir %{_prefix}/%{_lib}/pkgconfig
53%endif
54
55%bcond_with    debug
56%bcond_with    debuginfo
57%bcond_with    asan
58%bcond_with    ubsan
59%bcond_with    systemd
60%bcond_with    pam
61%bcond_without pyzfs
62
63# Generic enable switch for systemd
64%if %{with systemd}
65%define _systemd 1
66%endif
67
68# Distros below support systemd
69%if 0%{?rhel}%{?fedora}%{?centos}%{?suse_version}%{?openEuler}
70%define _systemd 1
71%endif
72
73# When not specified default to distribution provided version.
74%if %{undefined __use_python}
75%define __python                  /usr/bin/python3
76%define __python_pkg_version      3
77%else
78%define __python                  %{__use_python}
79%define __python_pkg_version      %{__use_python_pkg_version}
80%endif
81%define __python_sitelib          %(%{__python} -Esc "from distutils.sysconfig import get_python_lib; print(get_python_lib())" 2>/dev/null || %{__python} -Esc "import sysconfig; print(sysconfig.get_path('purelib'))")
82
83Name:           @PACKAGE@
84Version:        @VERSION@
85Release:        @RELEASE@%{?dist}
86Summary:        Commands to control the kernel modules and libraries
87
88Group:          System Environment/Kernel
89License:        @ZFS_META_LICENSE@
90URL:            https://github.com/openzfs/zfs
91Source0:        %{name}-%{version}.tar.gz
92BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
93Requires:       libzpool5%{?_isa} = %{version}-%{release}
94Requires:       libnvpair3%{?_isa} = %{version}-%{release}
95Requires:       libuutil3%{?_isa} = %{version}-%{release}
96Requires:       libzfs5%{?_isa} = %{version}-%{release}
97Requires:       %{name}-kmod = %{version}
98Provides:       %{name}-kmod-common = %{version}-%{release}
99Obsoletes:      spl <= %{version}
100
101# zfs-fuse provides the same commands and man pages that OpenZFS does.
102# Renaming those on either side would conflict with all available documentation.
103Conflicts:      zfs-fuse
104
105%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler}
106BuildRequires:  gcc, make
107BuildRequires:  zlib-devel
108BuildRequires:  libuuid-devel
109BuildRequires:  libblkid-devel
110BuildRequires:  libudev-devel
111BuildRequires:  libattr-devel
112BuildRequires:  openssl-devel
113%if 0%{?fedora}%{?openEuler} || 0%{?rhel} >= 8 || 0%{?centos} >= 8
114BuildRequires:  libtirpc-devel
115%endif
116
117%if (0%{?fedora}%{?suse_version}%{?openEuler}) || (0%{?rhel} && 0%{?rhel} < 9)
118# We don't directly use it, but if this isn't installed, rpmbuild as root can
119# crash+corrupt rpmdb
120# See issue #12071
121BuildRequires:  ncompress
122%endif
123
124Requires:       openssl
125%if 0%{?_systemd}
126BuildRequires: systemd
127%endif
128
129%endif
130
131%if 0%{?_systemd}
132Requires(post): systemd
133Requires(preun): systemd
134Requires(postun): systemd
135%endif
136
137# The zpool iostat/status -c scripts call some utilities like lsblk and iostat
138Requires:  util-linux
139Requires:  sysstat
140
141%description
142This package contains the core ZFS command line utilities.
143
144%package -n libzpool5
145Summary:        Native ZFS pool library for Linux
146Group:          System Environment/Kernel
147Obsoletes:      libzpool2 <= %{version}
148Obsoletes:      libzpool4 <= %{version}
149
150%description -n libzpool5
151This package contains the zpool library, which provides support
152for managing zpools
153
154%if %{defined ldconfig_scriptlets}
155%ldconfig_scriptlets -n libzpool5
156%else
157%post -n libzpool5 -p /sbin/ldconfig
158%postun -n libzpool5 -p /sbin/ldconfig
159%endif
160
161%package -n libnvpair3
162Summary:        Solaris name-value library for Linux
163Group:          System Environment/Kernel
164Obsoletes:      libnvpair1 <= %{version}
165
166%description -n libnvpair3
167This package contains routines for packing and unpacking name-value
168pairs.  This functionality is used to portably transport data across
169process boundaries, between kernel and user space, and can be used
170to write self describing data structures on disk.
171
172%if %{defined ldconfig_scriptlets}
173%ldconfig_scriptlets -n libnvpair3
174%else
175%post -n libnvpair3 -p /sbin/ldconfig
176%postun -n libnvpair3 -p /sbin/ldconfig
177%endif
178
179%package -n libuutil3
180Summary:        Solaris userland utility library for Linux
181Group:          System Environment/Kernel
182Obsoletes:      libuutil1 <= %{version}
183
184%description -n libuutil3
185This library provides a variety of compatibility functions for OpenZFS:
186 * libspl: The Solaris Porting Layer userland library, which provides APIs
187   that make it possible to run Solaris user code in a Linux environment
188   with relatively minimal modification.
189 * libavl: The Adelson-Velskii Landis balanced binary tree manipulation
190   library.
191 * libefi: The Extensible Firmware Interface library for GUID disk
192   partitioning.
193 * libshare: NFS, SMB, and iSCSI service integration for ZFS.
194
195%if %{defined ldconfig_scriptlets}
196%ldconfig_scriptlets -n libuutil3
197%else
198%post -n libuutil3 -p /sbin/ldconfig
199%postun -n libuutil3 -p /sbin/ldconfig
200%endif
201
202# The library version is encoded in the package name.  When updating the
203# version information it is important to add an obsoletes line below for
204# the previous version of the package.
205%package -n libzfs5
206Summary:        Native ZFS filesystem library for Linux
207Group:          System Environment/Kernel
208Obsoletes:      libzfs2 <= %{version}
209Obsoletes:      libzfs4 <= %{version}
210
211%description -n libzfs5
212This package provides support for managing ZFS filesystems
213
214%if %{defined ldconfig_scriptlets}
215%ldconfig_scriptlets -n libzfs5
216%else
217%post -n libzfs5 -p /sbin/ldconfig
218%postun -n libzfs5 -p /sbin/ldconfig
219%endif
220
221%package -n libzfs5-devel
222Summary:        Development headers
223Group:          System Environment/Kernel
224Requires:       libzfs5%{?_isa} = %{version}-%{release}
225Requires:       libzpool5%{?_isa} = %{version}-%{release}
226Requires:       libnvpair3%{?_isa} = %{version}-%{release}
227Requires:       libuutil3%{?_isa} = %{version}-%{release}
228Provides:       libzpool5-devel = %{version}-%{release}
229Provides:       libnvpair3-devel = %{version}-%{release}
230Provides:       libuutil3-devel = %{version}-%{release}
231Obsoletes:      zfs-devel <= %{version}
232Obsoletes:      libzfs2-devel <= %{version}
233Obsoletes:      libzfs4-devel <= %{version}
234
235%description -n libzfs5-devel
236This package contains the header files needed for building additional
237applications against the ZFS libraries.
238
239%package test
240Summary:        Test infrastructure
241Group:          System Environment/Kernel
242Requires:       %{name}%{?_isa} = %{version}-%{release}
243Requires:       parted
244Requires:       lsscsi
245Requires:       mdadm
246Requires:       bc
247Requires:       ksh
248Requires:       fio
249Requires:       acl
250Requires:       sudo
251Requires:       sysstat
252Requires:       libaio
253Requires:       python%{__python_pkg_version}
254%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler}
255BuildRequires:  libaio-devel
256%endif
257AutoReqProv:    no
258
259%description test
260This package contains test infrastructure and support scripts for
261validating the file system.
262
263%package dracut
264Summary:        Dracut module
265Group:          System Environment/Kernel
266BuildArch:	noarch
267Requires:       %{name} >= %{version}
268Requires:       dracut
269Requires:       /usr/bin/awk
270Requires:       grep
271
272%description dracut
273This package contains a dracut module used to construct an initramfs
274image which is ZFS aware.
275
276%if %{with pyzfs}
277# Enforce `python36-` package prefix for CentOS 7
278# since dependencies come from EPEL and are named this way
279%package -n python%{__python_pkg_version}-pyzfs
280Summary:        Python %{python_version} wrapper for libzfs_core
281Group:          Development/Languages/Python
282License:        Apache-2.0
283BuildArch:      noarch
284Requires:       libzfs5 = %{version}-%{release}
285Requires:       libnvpair3 = %{version}-%{release}
286Requires:       libffi
287Requires:       python%{__python_pkg_version}
288
289%if 0%{?centos} == 7
290Requires:       python36-cffi
291%else
292Requires:       python%{__python_pkg_version}-cffi
293%endif
294
295%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler}
296%if 0%{?centos} == 7
297BuildRequires:  python36-packaging
298BuildRequires:  python36-devel
299BuildRequires:  python36-cffi
300BuildRequires:  python36-setuptools
301%else
302BuildRequires:  python%{__python_pkg_version}-packaging
303BuildRequires:  python%{__python_pkg_version}-devel
304BuildRequires:  python%{__python_pkg_version}-cffi
305BuildRequires:  python%{__python_pkg_version}-setuptools
306%endif
307
308BuildRequires:  libffi-devel
309%endif
310
311%description -n python%{__python_pkg_version}-pyzfs
312This package provides a python wrapper for the libzfs_core C library.
313%endif
314
315%if 0%{?_initramfs}
316%package initramfs
317Summary:        Initramfs module
318Group:          System Environment/Kernel
319Requires:       %{name}%{?_isa} = %{version}-%{release}
320Requires:       initramfs-tools
321
322%description initramfs
323This package contains a initramfs module used to construct an initramfs
324image which is ZFS aware.
325%endif
326
327%if %{with pam}
328%package -n pam_zfs_key
329Summary:        PAM module for encrypted ZFS datasets
330
331%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler}
332BuildRequires:  pam-devel
333%endif
334
335%description -n pam_zfs_key
336This package contains the pam_zfs_key PAM module, which provides
337support for unlocking datasets on user login.
338%endif
339
340%prep
341%if %{with debug}
342    %define debug --enable-debug
343%else
344    %define debug --disable-debug
345%endif
346
347%if %{with debuginfo}
348    %define debuginfo --enable-debuginfo
349%else
350    %define debuginfo --disable-debuginfo
351%endif
352
353%if %{with asan}
354    %define asan --enable-asan
355%else
356    %define asan --disable-asan
357%endif
358
359%if %{with ubsan}
360    %define ubsan --enable-ubsan
361%else
362    %define ubsan --disable-ubsan
363%endif
364
365%if 0%{?_systemd}
366    %define systemd --enable-systemd --with-systemdunitdir=%{_unitdir} --with-systemdpresetdir=%{_presetdir} --with-systemdmodulesloaddir=%{_modulesloaddir} --with-systemdgeneratordir=%{_systemdgeneratordir} --disable-sysvinit
367    %define systemd_svcs zfs-import-cache.service zfs-import-scan.service zfs-mount.service zfs-share.service zfs-zed.service zfs.target zfs-import.target zfs-volume-wait.service zfs-volumes.target
368%else
369    %define systemd --enable-sysvinit --disable-systemd
370%endif
371
372%if %{with pyzfs}
373    %define pyzfs --enable-pyzfs
374%else
375    %define pyzfs --disable-pyzfs
376%endif
377
378%if %{with pam}
379    %define pam --enable-pam
380%else
381    %define pam --disable-pam
382%endif
383
384%setup -q
385
386%build
387%configure \
388    --with-config=user \
389    --with-udevdir=%{_udevdir} \
390    --with-udevruledir=%{_udevruledir} \
391    --with-dracutdir=%{_dracutdir} \
392    --with-pamconfigsdir=%{_datadir}/pam-configs \
393    --with-pammoduledir=%{_libdir}/security \
394    --with-python=%{__python} \
395    --with-pkgconfigdir=%{_pkgconfigdir} \
396    --disable-static \
397    %{debug} \
398    %{debuginfo} \
399    %{asan} \
400    %{ubsan} \
401    %{systemd} \
402    %{pam} \
403    %{pyzfs}
404make %{?_smp_mflags}
405
406%install
407%{__rm} -rf $RPM_BUILD_ROOT
408make install DESTDIR=%{?buildroot}
409find %{?buildroot}%{_libdir} -name '*.la' -exec rm -f {} \;
410%if 0%{!?__brp_mangle_shebangs:1}
411find %{?buildroot}%{_bindir} \
412    \( -name arc_summary -or -name arcstat -or -name dbufstat \
413    -or -name zilstat \) \
414    -exec %{__sed} -i 's|^#!.*|#!%{__python}|' {} \;
415find %{?buildroot}%{_datadir} \
416    \( -name test-runner.py -or -name zts-report.py \) \
417    -exec %{__sed} -i 's|^#!.*|#!%{__python}|' {} \;
418%endif
419
420%post
421%if 0%{?_systemd}
422%if 0%{?systemd_post:1}
423%systemd_post %{systemd_svcs}
424%else
425if [ "$1" = "1" -o "$1" = "install" ] ; then
426    # Initial installation
427    systemctl preset %{systemd_svcs} >/dev/null || true
428fi
429%endif
430%else
431if [ -x /sbin/chkconfig ]; then
432    /sbin/chkconfig --add zfs-import
433    /sbin/chkconfig --add zfs-load-key
434    /sbin/chkconfig --add zfs-mount
435    /sbin/chkconfig --add zfs-share
436    /sbin/chkconfig --add zfs-zed
437fi
438%endif
439exit 0
440
441# On RHEL/CentOS 7 the static nodes aren't refreshed by default after
442# installing a package.  This is the default behavior for Fedora.
443%posttrans
444%if 0%{?rhel} == 7 || 0%{?centos} == 7
445systemctl restart kmod-static-nodes
446systemctl restart systemd-tmpfiles-setup-dev
447udevadm trigger
448%endif
449
450%preun
451%if 0%{?_systemd}
452%if 0%{?systemd_preun:1}
453%systemd_preun %{systemd_svcs}
454%else
455if [ "$1" = "0" -o "$1" = "remove" ] ; then
456    # Package removal, not upgrade
457    systemctl --no-reload disable %{systemd_svcs} >/dev/null || true
458    systemctl stop %{systemd_svcs} >/dev/null || true
459fi
460%endif
461%else
462if [ "$1" = "0" -o "$1" = "remove" ] && [ -x /sbin/chkconfig ]; then
463    /sbin/chkconfig --del zfs-import
464    /sbin/chkconfig --del zfs-load-key
465    /sbin/chkconfig --del zfs-mount
466    /sbin/chkconfig --del zfs-share
467    /sbin/chkconfig --del zfs-zed
468fi
469%endif
470exit 0
471
472%postun
473%if 0%{?_systemd}
474%if 0%{?systemd_postun:1}
475%systemd_postun %{systemd_svcs}
476%else
477systemctl --system daemon-reload >/dev/null || true
478%endif
479%endif
480
481%files
482# Core utilities
483%{_sbindir}/*
484%{_bindir}/raidz_test
485%{_sbindir}/zgenhostid
486%{_bindir}/zvol_wait
487# Optional Python 3 scripts
488%{_bindir}/arc_summary
489%{_bindir}/arcstat
490%{_bindir}/dbufstat
491%{_bindir}/zilstat
492# Man pages
493%{_mandir}/man1/*
494%{_mandir}/man4/*
495%{_mandir}/man5/*
496%{_mandir}/man7/*
497%{_mandir}/man8/*
498# Configuration files and scripts
499%{_libexecdir}/%{name}
500%{_udevdir}/vdev_id
501%{_udevdir}/zvol_id
502%{_udevdir}/rules.d/*
503%{_datadir}/%{name}/compatibility.d
504%if ! 0%{?_systemd} || 0%{?_initramfs}
505# Files needed for sysvinit and initramfs-tools
506%{_sysconfdir}/%{name}/zfs-functions
507%config(noreplace) %{_initconfdir}/zfs
508%else
509%exclude %{_sysconfdir}/%{name}/zfs-functions
510%exclude %{_initconfdir}/zfs
511%endif
512%if 0%{?_systemd}
513%{_unitdir}/*
514%{_presetdir}/*
515%{_modulesloaddir}/*
516%{_systemdgeneratordir}/*
517%else
518%config(noreplace) %{_sysconfdir}/init.d/*
519%endif
520%config(noreplace) %{_sysconfdir}/%{name}/zed.d/*
521%config(noreplace) %{_sysconfdir}/%{name}/zpool.d/*
522%config(noreplace) %{_sysconfdir}/%{name}/vdev_id.conf.*.example
523%attr(440, root, root) %config(noreplace) %{_sysconfdir}/sudoers.d/*
524
525%config(noreplace) %{_sysconfdir}/bash_completion.d/zfs
526
527%files -n libzpool5
528%{_libdir}/libzpool.so.*
529
530%files -n libnvpair3
531%{_libdir}/libnvpair.so.*
532
533%files -n libuutil3
534%{_libdir}/libuutil.so.*
535
536%files -n libzfs5
537%{_libdir}/libzfs*.so.*
538
539%files -n libzfs5-devel
540%{_pkgconfigdir}/libzfs.pc
541%{_pkgconfigdir}/libzfsbootenv.pc
542%{_pkgconfigdir}/libzfs_core.pc
543%{_libdir}/*.so
544%{_includedir}/*
545%doc AUTHORS COPYRIGHT LICENSE NOTICE README.md
546
547%files test
548%{_datadir}/%{name}/zfs-tests
549%{_datadir}/%{name}/test-runner
550%{_datadir}/%{name}/runfiles
551%{_datadir}/%{name}/*.sh
552
553%files dracut
554%doc contrib/dracut/README.md
555%{_dracutdir}/modules.d/*
556
557%if %{with pyzfs}
558%files -n python%{__python_pkg_version}-pyzfs
559%doc contrib/pyzfs/README
560%doc contrib/pyzfs/LICENSE
561%defattr(-,root,root,-)
562%{__python_sitelib}/libzfs_core/*
563%{__python_sitelib}/pyzfs*
564%endif
565
566%if 0%{?_initramfs}
567%files initramfs
568%doc contrib/initramfs/README.md
569/usr/share/initramfs-tools/*
570%else
571# Since we're not building the initramfs package,
572# ignore those files.
573%exclude /usr/share/initramfs-tools
574%endif
575
576%if %{with pam}
577%files -n pam_zfs_key
578%{_libdir}/security/*
579%{_datadir}/pam-configs/*
580%endif
581