diff --git a/Makefile.am b/Makefile.am index 4bbd952b988..f50cdf19b21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = src perl scripts corepkgs doc misc tests EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \ - nix.conf.example NEWS version + nix.conf.example NEWS version misc/systemd/nix-worker.service pkginclude_HEADERS = config.h diff --git a/misc/systemd/nix-worker.service b/misc/systemd/nix-worker.service new file mode 100644 index 00000000000..2ededfea806 --- /dev/null +++ b/misc/systemd/nix-worker.service @@ -0,0 +1,10 @@ +[Unit] +Description=Helper daemon for managing secure, multi-user Nix stores +After=syslog.target + +[Service] +Type=simple +ExecStart=/usr/bin/nix-worker --daemon + +[Install] +WantedBy=multi-user.target diff --git a/nix.spec.in b/nix.spec.in index 4f63f029f58..44ea8d7c947 100644 --- a/nix.spec.in +++ b/nix.spec.in @@ -1,29 +1,26 @@ -%define enable_setuid "" -%define nix_user "nix" -%define nix_group "nix" - -# If set, the Nix user and group will be created by the RPM -# pre-install script. -%define nix_user_uid "" -%define nix_group_gid "" +%global nixbld_user "nix-builder-" +%global nixbld_group "nix-builders" Summary: The Nix software deployment system Name: nix Version: @version@ -Release: 1 -License: GPL -Group: Software Deployment +Release: 2%{?dist} +License: LGPLv2+ +%if 0%{?rhel} +Group: Applications/System +%endif URL: http://nixos.org/ -Source0: %{name}-@version@.tar.bz2 -BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot -Prefix: /usr +Source0: %{name}-%{version}.tar.bz2 +%if 0%{?el5} +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +%endif +BuildRequires: perl(DBD::SQLite) +BuildRequires: perl(DBI) +BuildRequires: perl(ExtUtils::ParseXS) Requires: /usr/bin/perl Requires: curl Requires: perl-DBD-SQLite -Requires: perl-devel Requires: bzip2 -Requires: bzip2-libs -Requires: sqlite BuildRequires: bzip2-devel BuildRequires: sqlite-devel @@ -31,7 +28,6 @@ BuildRequires: sqlite-devel Provides: perl(Nix::SSH) %description - Nix is a purely functional package manager. It allows multiple versions of a package to be installed side-by-side, ensures that dependency specifications are complete, supports atomic upgrades and @@ -39,52 +35,181 @@ rollbacks, allows non-root users to install software, and has many other features. It is the basis of the NixOS Linux distribution, but it can be used equally well under other Unix systems. +%package devel +Summary: Development files for %{name} +%if 0%{?rhel} +Group: Development/Libraries +%endif +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + + +%package doc +Summary: Documentation files for %{name} +%if 0%{?rhel} +Group: Documentation +%endif +BuildArch: noarch +Requires: %{name} = %{version}-%{release} + +%description doc +The %{name}-doc package contains documentation files for %{name}. + + +%package -n emacs-%{name} +Summary: Nix mode for Emacs +%if 0%{?rhel} +Group: Applications/Editors +%endif +BuildArch: noarch +BuildRequires: emacs +Requires: emacs(bin) >= %{_emacs_version} + +%description -n emacs-%{name} +This package provides a major mode for editing Nix expressions. + +%package -n emacs-%{name}-el +Summary: Elisp source files for emacs-%{name} +%if 0%{?rhel} +Group: Applications/Editors +%endif +BuildArch: noarch +Requires: emacs-%{name} = %{version}-%{release} + +%description -n emacs-%{name}-el +This package contains the elisp source file for the Nix major mode for +GNU Emacs. You do not need to install this package to run Nix. Install +the emacs-%{name} package to edit Nix expressions with GNU Emacs. + + %prep %setup -q +# Install Perl modules to vendor_perl +# configure.ac need to be changed to make this global; however, this will +# also affect NixOS. Use discretion. +%{__sed} -i 's|perl5/site_perl/$perlversion/$perlarchname|perl5/vendor_perl|' \ + configure + %build extraFlags= -if test -n "%{enable_setuid}"; then - extraFlags="$extraFlags --enable-setuid" - if test -n "%{nix_user}"; then - extraFlags="$extraFlags --with-nix-user=%{nix_user}" - fi - if test -n "%{nix_group}"; then - extraFlags="$extraFlags --with-nix-group=%{nix_group}" - fi -fi -./configure --prefix=%{_prefix} --sysconfdir=/etc $extraFlags -make -make check +# - override docdir so large documentation files are owned by the +# -doc subpackage +# - set localstatedir by hand to the preferred nix value +%configure --localstatedir=/nix/var \ + --docdir=%{_defaultdocdir}/%{name}-doc-%{version} \ + $extraFlags +make %{?_smp_flags} +%{_emacs_bytecompile} misc/emacs/nix-mode.el + %install +%if 0%{?el5} rm -rf $RPM_BUILD_ROOT +%endif make DESTDIR=$RPM_BUILD_ROOT install -rm $RPM_BUILD_ROOT/etc/nix/nix.conf -strip $RPM_BUILD_ROOT/%{_prefix}/bin/* || true + +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + +# Fix symlink: we want to link to the versioned soname, not to the +# unversioned one that'd be put in -devel +pushd $RPM_BUILD_ROOT%{perl_vendorarch}/auto/Nix/Store +ln -sf %{_libdir}/nix/libNixStore.so.0 Store.so +popd + +# Specify build users group +sed -i "s|#build-users-group =$|build-users-group = %{nixbld_group}|" \ + $RPM_BUILD_ROOT%{_sysconfdir}/nix/nix.conf +# ... and delete the example configuration +rm $RPM_BUILD_ROOT%{_sysconfdir}/nix/nix.conf.example + +# make per-user directories +for d in profiles gcroots; +do + mkdir $RPM_BUILD_ROOT/nix/var/nix/$d/per-user + chmod 1777 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user +done + +# fix permission of nix profile +# (until this is fixed in the relevant Makefile) +chmod -x $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/nix.sh + +# systemd not available on RHEL yet +%if ! 0%{?rhel} +# install systemd service descriptor +mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system +cp -p misc/systemd/nix-worker.service \ + $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system/ +%endif + +# Copy the byte-compiled mode file by hand +cp -p misc/emacs/nix-mode.elc $RPM_BUILD_ROOT%{_emacs_sitelispdir}/ + +# we ship this file in the base package +rm $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}-doc-%{version}/README + + +%check +make check + %clean rm -rf $RPM_BUILD_ROOT + %pre -if test -n "%{nix_group_gid}"; then - /usr/sbin/groupadd -g %{nix_group_gid} %{nix_group} || true -fi -if test -n "%{nix_user_uid}"; then - /usr/sbin/useradd -c "Nix" -u %{nix_user_uid} \ - -s /sbin/nologin -r -d /var/empty %{nix_user} \ - -g %{nix_group} || true -fi +getent group %{nixbld_group} >/dev/null || groupadd -r %{nixbld_group} +for i in $(seq 10); +do + getent passwd %{nixbld_user}$i >/dev/null || \ + useradd -r -g %{nixbld_group} -G %{nixbld_group} -d /var/empty \ + -s %{_sbindir}/nologin \ + -c "Nix build user $i" %{nixbld_user}$i +done + +%post +chgrp %{nixbld_group} /nix/store +chmod 1775 /nix/store +%if ! 0%{?rhel} +# Enable and start Nix worker +systemctl enable nix-worker.service +systemctl start nix-worker.service +%endif %files -#%defattr(-,root,root) -%{_prefix}/bin -%{_prefix}/lib -%{_prefix}/libexec -%{_prefix}/include -%{_prefix}/share -/etc/profile.d/nix.sh -/nix/var -/nix/store -%config -/etc/nix +%doc COPYING AUTHORS README +%{_bindir}/nix-* +%dir %{_libdir}/nix +%{_libdir}/nix/*.so.* +%{perl_vendorarch}/* +%exclude %dir %{perl_vendorarch}/auto/ +%{_prefix}/libexec/* +%if ! 0%{?rhel} +%{_prefix}/lib/systemd/system/nix-worker.service +%endif +%{_datadir}/emacs/site-lisp/nix-mode.el +%{_datadir}/nix +%{_mandir}/man1/nix-*.1* +%{_mandir}/man8/nix-*.8* +%config(noreplace) %{_sysconfdir}/profile.d/nix.sh +/nix +%dir %{_sysconfdir}/nix +%config(noreplace) %{_sysconfdir}/nix/nix.conf + +%files devel +%{_includedir}/nix +%{_libdir}/nix/*.so + +%files doc +%docdir %{_defaultdocdir}/%{name}-doc-%{version} +%{_defaultdocdir}/%{name}-doc-%{version} + +%files -n emacs-%{name} +%{_emacs_sitelispdir}/*.elc +#{_emacs_sitestartdir}/*.el + +%files -n emacs-%{name}-el +%{_emacs_sitelispdir}/*.el diff --git a/scripts/Makefile.am b/scripts/Makefile.am index a5703760d1f..18a59dbdb6f 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -11,7 +11,7 @@ nix-pull nix-push: download-using-manifests.pl install-exec-local: download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl $(INSTALL) -d $(DESTDIR)$(sysconfdir)/profile.d - $(INSTALL_PROGRAM) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh + $(INSTALL_DATA) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh $(INSTALL) -d $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix diff --git a/scripts/nix-profile.sh.in b/scripts/nix-profile.sh.in index 83953134973..d343385cc1e 100644 --- a/scripts/nix-profile.sh.in +++ b/scripts/nix-profile.sh.in @@ -1,11 +1,50 @@ -if test -n "$HOME"; then - NIX_LINK="$HOME/.nix-profile" +export NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER +export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile" - if ! test -L "$NIX_LINK"; then - echo "creating $NIX_LINK" >&2 - _NIX_DEF_LINK=@localstatedir@/nix/profiles/default - @coreutils@/ln -s "$_NIX_DEF_LINK" "$NIX_LINK" +# Set up the per-user profile. +mkdir -m 0755 -p $NIX_USER_PROFILE_DIR +if test "$(stat --printf '%u' $NIX_USER_PROFILE_DIR)" != "$(id -u)"; then + echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2 +fi + +if ! test -L $HOME/.nix-profile; then + echo "creating $HOME/.nix-profile" >&2 + if test "$USER" != root; then + @coreutils@/ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile + else + # Root installs in the system-wide profile by default. + @coreutils@/ln -s /nix/var/nix/profiles/default $HOME/.nix-profile fi +fi + +export PATH="$HOME/.nix-profile/bin:$PATH" + +# Subscribe the root user to the NixOS channel by default. +if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then + echo "http://nixos.org/releases/nixos/channels/nixos-unstable nixos" > $HOME/.nix-channels +fi + +# Create the per-user garbage collector roots directory. +NIX_USER_GCROOTS_DIR=@localstatedir@/nix/gcroots/per-user/$USER +mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR +if test "$(stat --printf '%u' $NIX_USER_GCROOTS_DIR)" != "$(id -u)"; then + echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2 +fi + +# Set up a default Nix expression from which to install stuff. +if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then + echo "creating $HOME/.nix-defexpr" >&2 + rm -f $HOME/.nix-defexpr + mkdir $HOME/.nix-defexpr + if [ "$USER" != root ]; then + @coreutils@/ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root + fi +fi - export PATH=$NIX_LINK/bin:$PATH +# Set up secure multi-user builds: non-root users build through the +# Nix daemon. +if test "$USER" != root; then + export NIX_REMOTE=daemon +else + unset NIX_REMOTE fi