Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
500 changes: 0 additions & 500 deletions nixos/modules/system/activation/switch-to-configuration.pl

This file was deleted.

612 changes: 612 additions & 0 deletions nixos/modules/system/activation/switch-to-configuration.py

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions nixos/modules/system/activation/top-level.nix
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ let

mkdir $out/bin
export localeArchive="${config.i18n.glibcLocales}/lib/locale/locale-archive"
substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration
substituteAll ${./switch-to-configuration.py} $out/bin/switch-to-configuration
chmod +x $out/bin/switch-to-configuration

echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies
Expand Down Expand Up @@ -122,8 +122,9 @@ let
configurationName = config.boot.loader.grub.configurationName;

# Needed by switch-to-configuration.

perl = "${pkgs.perl}/bin/perl " + (concatMapStringsSep " " (lib: "-I${lib}/${pkgs.perl.libPrefix}") (with pkgs.perlPackages; [ FileSlurp NetDBus XMLParser XMLTwig ]));
python =
let env = pkgs.python3.withPackages (pypkgs: [ pypkgs.dbus-python ]);
in "${env}/bin/python3";
};

# Handle assertions and warnings
Expand Down
2 changes: 1 addition & 1 deletion nixos/modules/system/etc/etc.nix
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ in
''
# Set up the statically computed bits of /etc.
echo "setting up /etc..."
${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl ${./setup-etc.pl} ${etc}/etc
${pkgs.python3}/bin/python3 ${./setup-etc.py} ${etc}/etc
'';

};
Expand Down
140 changes: 0 additions & 140 deletions nixos/modules/system/etc/setup-etc.pl

This file was deleted.

178 changes: 178 additions & 0 deletions nixos/modules/system/etc/setup-etc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import argparse
import os
import os.path
from pathlib import Path
from pwd import getpwnam
from grp import getgrnam
import shutil
import sys
from typing import List, Tuple, Set

STATIC = Path("/etc/static")
CLEAN_FILE = Path("/etc/.clean")

def warn(msg: str) -> None:
print('warning:', msg, file=sys.stderr)

def atomic_symlink(source: Path, target: Path) -> None:
tmp = Path("{target}.tmp".format(target=target))
tmp.unlink()
tmp.symlink_to(source)
tmp.rename(target)

def atomic_symlink_or_warn(source: Path, target: Path) -> None:
try:
atomic_symlink(source, target)
except IOError as exc:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With python3 you usually want to catch OSError. IOError is just a superset.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warn("error creating link '{target}': {exc}". \
format(target=target, exc=exc))

def is_static(path: Path) -> bool:
"""
Returns True if the argument points to the files in /etc/static. That means
either argument is a symlink to a file in /etc/static or a directory with
all children being static.
"""

if path.is_symlink():
target = path.resolve()
res = os.path.commonprefix([target, STATIC]) == STATIC # type: bool
return res

if path.is_dir():
return all(is_static(ent) for ent in path.iterdir())

return False

def cleanup() -> None:
"""
Remove dangling symlinks that point to /etc/static. These are
configuration files that existed in a previous configuration but not
in the current one. For efficiency, don't look under /etc/nixos
(where all the NixOS sources live).
"""
for root, dirs, files in os.walk('/etc'):
if root == '/etc':
dirs.remove('nixos')

for f in files:
path = Path(root) / Path(f)
if path.is_symlink():
target = path.resolve()
if os.path.commonprefix([target, STATIC]) == STATIC:
x = STATIC / path.relative_to('/etc')
if x.is_symlink():
print("removing obsolete symlink '{path}'".format(path=path),
file=sys.stderr)
path.unlink()

def link_statics(etc: Path) -> Tuple[Set[Path], Set[Path]]:
"""
For every file in the etc tree, create a corresponding symlink in
/etc to /etc/static. The indirection through /etc/static is to make
switching to a new configuration somewhat more atomic.
"""

clean = open(CLEAN_FILE, 'a')
created = set()
copied = set()
for root, dirs, files in os.walk(etc):
for f in files:
path = Path(root) / Path(f)
if os.path.commonprefix([etc, path]) != etc:
continue
fn = path.relative_to(etc)
target = Path("/etc") / f
target.parent.mkdir(parents=True)
created.add(fn)

# Rename doesn't work if target is directory.
if Path(f).is_symlink() and target.is_dir():
if is_static(target):
try:
shutil.rmtree(target)
except IOError as exc:
warn("error trying to remove '{target}': {exc}". \
format(target=target, exc=exc))
else:
warn("$target directory contains user files. Symlinking may fail.")

meta_f = Path("{f}.mode".format(f=f))
if meta_f.exists():
mode = open(meta_f, 'r').read().strip()
if mode == 'direct-symlink':
src = (STATIC / fn).resolve()
atomic_symlink_or_warn(src, target)
else:
user = open("{f}.uid".format(f=f)).read().strip()
grp = open("{f}.gid".format(f=f)).read().strip()
uid = getpwnam(user).pw_uid
gid = getgrnam(grp).gr_gid

src = STATIC / fn
tmp = Path("{target}.tmp".format(target=target))
try:
shutil.copyfile(src, tmp)
except IOError as exc:
warn("error copying from '{src}' to '{tmp}': {exc}". \
format(src=src, tmp=tmp, exc=exc))

try:
os.chown(tmp, uid, gid)
except IOError as exc:
warn("error setting owner of '{tmp}': {exc}". \
format(tmp=tmp, exc=exc))

try:
os.chmod(tmp, int(mode, 8))
except IOError as exc:
warn("error setting mode of '{tmp}': {exc}". \
format(tmp=tmp, exc=exc))

try:
tmp.rename(target)
except IOError as exc:
warn("error renaming '{tmp}' to '{target}': {exc}". \
format(tmp=tmp, target=target, exc=exc))

copied.add(fn)
print(fn, file=clean)

elif Path(f).is_symlink():
atomic_symlink_or_warn(STATIC / fn, target)

return (created, copied)

def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('etc')
args = parser.parse_args()
etc = args.etc

# Atomically update /etc/static to point at the etc files of the
# current configuration.
atomic_symlink(etc, STATIC)

cleanup()

# Use /etc/.clean to keep track of copied files.
old_copied = [] # type: List[str]
if CLEAN_FILE.is_file():
old_copied += [ line.strip() for line in CLEAN_FILE.read_text().split('\n') ]

created, copied = link_statics(etc)

# Delete files that were copied in a previous version but not in the
# current.
for f in old_copied:
if f not in created:
fn = Path("/etc") / f
print("removing obsolete file '{f}'...".format(f=f),
file=sys.stderr)
fn.unlink()

# Rewrite /etc/.clean
CLEAN_FILE.write_text('\n'.join(str(p) for p in copied))

if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion pkgs/data/misc/shared-mime-info/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ stdenv.mkDerivation rec {
};

nativeBuildInputs = [
pkgconfig gettext intltool perl perlXMLParser libxml2 glib
pkgconfig gettext intltool perl perlXMLParser
];
buildInputs = [ libxml2 glib ];

meta = with stdenv.lib; {
inherit version;
Expand Down
5 changes: 4 additions & 1 deletion pkgs/development/libraries/dbus-glib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ stdenv.mkDerivation rec {
outputs = [ "out" "dev" "devdoc" ];
outputBin = "dev";

nativeBuildInputs = [ pkgconfig gettext ];
nativeBuildInputs = [
pkgconfig gettext
glib # for glib-marshal
];

buildInputs = [ expat libiconv ];

Expand Down
10 changes: 5 additions & 5 deletions pkgs/development/tools/build-managers/meson/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ python3Packages.buildPythonApplication rec {

crossFile = writeTextDir "cross-file.conf" ''
[binaries]
Comment thread
bgamari marked this conversation as resolved.
Outdated
c = '${stdenv.cc.targetPrefix}cc'
cpp = '${stdenv.cc.targetPrefix}c++'
ar = '${stdenv.cc.bintools.targetPrefix}ar'
strip = '${stdenv.cc.bintools.targetPrefix}strip'
c = '${stdenv.targetPlatform.config}-cc'
cpp = '${stdenv.targetPlatform.config}-c++'
ar = '${stdenv.targetPlatform.config}-ar'
strip = '${stdenv.targetPlatform.config}-strip'
pkgconfig = 'pkg-config'

[properties]
Expand All @@ -70,7 +70,7 @@ python3Packages.buildPythonApplication rec {

inherit (stdenv) cc;

isCross = stdenv.buildPlatform != stdenv.hostPlatform;
isCross = stdenv.targetPlatform != stdenv.hostPlatform;

meta = with lib; {
homepage = http://mesonbuild.com;
Expand Down