Merge remote-tracking branch 'cloudkrebs/master' into pre-merge

This commit is contained in:
makefu 2015-09-23 11:57:27 +02:00
commit b88363ce1a
23 changed files with 640 additions and 36 deletions

View File

@ -21,6 +21,10 @@ else ifdef system
deploy:;@
make eval system=$(system) get=config.krebs.build.script filter=json | sh
.PHONY: infest
infest:;@
make eval system=$(system) get=config.krebs.build.infest filter=json | sh
.PHONY: eval
eval:
@

View File

@ -59,8 +59,6 @@ let
--exclude .graveyard \
--exclude old \
--rsync-path="mkdir -p \"$2\" && rsync" \
--usermap=\*:0 \
--groupmap=\*:0 \
--delete-excluded \
-vrLptgoD \
"$src" "$dst"
@ -123,6 +121,112 @@ let
exec "$profile"/bin/switch-to-configuration switch
EOF
'';
};
infest = mkOption {
type = types.str;
default = ''
#! /bin/sh
set -efux
target=${escapeShellArg cfg.build.target}
push(){(
src=$1/
dst=$target:/mnt$2
rsync \
--exclude .git \
--exclude .graveyard \
--exclude old \
--rsync-path="mkdir -p \"/mnt$2\" && rsync" \
--delete-excluded \
-vrLptgoD \
"$src" "$dst"
)}
cat krebs/4lib/infest/1prepare | ssh "$target"
cat krebs/4lib/infest/2install-nix | ssh "$target"
${concatStrings (mapAttrsToList (name: { url, rev, ... }:
optionalString (rev == null) ''
push ${toString (map escapeShellArg [
"${url}"
"/root/src/${name}"
])}
'') config.deps)}
ssh -S none "$target" /bin/sh <<\EOF
set -efux
fetch(){(
url=$1
rev=$2
dst=$3
mkdir -p "$dst"
cd "$dst"
if ! test -e .git; then
git init
fi
if ! cur_url=$(git config remote.origin.url 2>/dev/null); then
git remote add origin "$url"
elif test "$cur_url" != "$url"; then
git remote set-url origin "$url"
fi
if test "$(git rev-parse --verify HEAD 2>/dev/null)" != "$rev"; then
git fetch origin
git checkout "$rev" -- .
git checkout -q "$rev"
git submodule init
git submodule update
fi
git clean -dxf
)}
${concatStrings (mapAttrsToList (name: { url, rev, ... }:
optionalString (rev != null) ''
fetch ${toString (map escapeShellArg [
url
rev
"/mnt/root/src/${name}"
])}
'') config.deps)}
export PATH=/root/.nix-profile/bin:/root/.nix-profile/sbin:$PATH
sed < "$(type -p nixos-install)" > nixos-install '
/^echo "building the system configuration..."/,/--set -A system/{
s/.*/# &/
s@.*--set -A system.*@&\n${concatStringsSep " " [
"NIX_PATH=/mnt/root/src/"
"nix-env"
"-Q"
"-p /nix/var/nix/profiles/system"
"-f \"<stockholm>\""
"--set"
"-A system"
"--argstr user-name ${escapeShellArg cfg.build.user.name}"
"--argstr system-name ${escapeShellArg cfg.build.host.name}"
]}@
}
'
sed -i 's/^nixpkgs=.*$/#&/' nixos-install
chmod +x nixos-install
echo {} > /root/dummy.nix
echo build system...
profile=/nix/var/nix/profiles/system
NIXOS_CONFIG=/root/dummy.nix \
./nixos-install -I /root/src/
#nl -bp nixos-install
EOF
cat krebs/4lib/infest/4finalize | ssh "$target"
'';
};
host = mkOption {
@ -219,6 +323,37 @@ let
lass-imp = {
hosts = addNames {
echelon = {
cores = 4;
dc = "lass"; #dc = "cac";
nets = rec {
internet = {
addrs4 = ["162.248.8.63"];
aliases = [
"echelon.internet"
];
};
retiolum = {
via = internet;
addrs4 = ["10.243.206.103"];
addrs6 = ["42:941e:2816:35f4:5c5e:206b:3f0b:f763"];
aliases = [
"echelon.retiolum"
"cgit.echelon.retiolum"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA92ybhDahtGybpAkUNlG5Elxw05MVY4Pg7yK0dQugB4nVq+pnmi78
DOMeIciecMHmJM8n9UlUU0eWZVCgHeVd23d6J0hTHCv24p24uHEGGy7XlO/dPJ6A
IjROYU0l8c03pipdJ3cDBx6riArSglwmZJ7xH/Iw0BUhRZrPqbtijY7EcG2wc+8K
N9N9mBofVMl4EcBiDR/eecK+ro8OkeOmYPtYgFJLvxTYXiPIhOxMAlkOY2fpin/t
cgFLUFuN4ag751XjjcNpVovVq95vdg+VhKrrNVWZjJt03owW81BzoryY6CD2kIPq
UxK89zEdeYOUT7AxaT/5V5v41IvGFZxCzwIDAQAB
-----END RSA PUBLIC KEY-----
'';
};
};
};
cloudkrebs = {
cores = 1;
dc = "lass"; #dc = "cac";
@ -683,6 +818,31 @@ let
};
secure = true;
};
xu = {
cores = 4;
# TODO xu is mobile, so dc means "home data center"
dc = "tv"; #dc = "gg23";
nets = {
retiolum = {
addrs4 = ["10.243.13.38"];
addrs6 = ["42:0:0:0:0:0:0:1338"];
aliases = [
"xu.retiolum"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAl3l7IWbfbkVgaJFM3s9g2UCh2rmqoTba16Of7NNWMj05L/hIkUsQ
uc43/QzidWh/4gEaq5MQ7JpLyzVBQYRJkNlPRF/Z07KdLBskAZCjDYdYue9BrziX
8s2Irs2+FNbCK2LqtrPhbcXQJvixsk6vjl2OBpWTDUcDEsk+D1YQilxdtyUzCUkw
mmRo/mzNsLZsYlSgZ6El/ZLkRdtexAzGxJ0DrukpDR0uqXXkp7jUaxRCZ+Cwanvj
4I1Hu5aHzWB7KJ1SIvpX3a4f+mun1gh3TPqWP5PUqJok1PSuScz6P2UGaLZZyH63
4o+9nGJPuzb9bpMVRaVGtKXd39jwY7mbqwIDAQAB
-----END RSA PUBLIC KEY-----
'';
};
};
secure = true;
};
};
users = addNames {
mv = {

View File

@ -0,0 +1,74 @@
#! /bin/sh
set -efu
prepare() {(
if test -e /etc/os-release; then
. /etc/os-release
case $ID in
centos)
case $VERSION_ID in
7)
prepare_centos7 "$@"
exit
;;
esac
;;
esac
fi
echo "$0 prepare: unknown OS" >&2
exit -1
)}
prepare_centos7() {
type bzip2 2>/dev/null || yum install -y bzip2
type git 2>/dev/null || yum install -y git
type rsync 2>/dev/null || yum install -y rsync
if ! getent group nixbld >/dev/null; then
groupadd -g 30000 -r nixbld
fi
for i in `seq 1 10`; do
if ! getent passwd nixbld$i 2>/dev/null; then
useradd \
-c "CentOS Nix build user $i" \
-d /var/empty \
-g 30000 \
-G 30000 \
-l \
-M \
-s /sbin/nologin \
-u $(expr 30000 + $i) \
nixbld$i
rm -f /var/spool/mail/nixbld$i
fi
done
#
# mount install directory
#
if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt type xfs'; then
mkdir -p /newshit
mount --bind /newshit /mnt
fi
if ! mount | grep -Fq '/dev/sda1 on /mnt/boot type xfs'; then
mkdir -p /mnt/boot
mount /dev/sda1 /mnt/boot
fi
mount | grep 'on /mnt\>' >&2
#
# prepare install directory
#
mkdir -p /mnt/etc/nixos
mkdir -m 0555 -p /mnt/var/empty
if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt/root type xfs'; then
mkdir -p /mnt/root
mount --bind /root /mnt/root
fi
}
prepare "$@"

View File

@ -0,0 +1,57 @@
#! /bin/sh
set -efu
nix_url=https://nixos.org/releases/nix/nix-1.10/nix-1.10-x86_64-linux.tar.bz2
nix_sha256="504f7a3a85fceffb8766ae5e1005de9e02e489742f5a63cc3e7552120b138bf4"
install-nix() {(
# install nix on host (cf. https://nixos.org/nix/install)
if ! test -e /root/.nix-profile/etc/profile.d/nix.sh; then
(
verify() {
printf '%s %s\n' $nix_sha256 $(basename $nix_url) | sha256sum -c
}
if ! verify; then
curl -C - -O "$nix_url"
verify
fi
)
nix_src_dir=$(basename $nix_url .tar.bz2)
tar jxf $nix_src_dir.tar.bz2
mkdir -v -m 0755 -p /nix
$nix_src_dir/install
fi
#TODO: make this general or move to 1prepare
if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt/nix type xfs'; then
mkdir -p /mnt/nix
mount --bind /nix /mnt/nix
fi
. /root/.nix-profile/etc/profile.d/nix.sh
for i in \
bash \
coreutils \
# This line intentionally left blank.
do
if ! nix-env -q $i | grep -q .; then
nix-env -iA nixpkgs.pkgs.$i
fi
done
# install nixos-install
if ! type nixos-install 2>/dev/null; then
nixpkgs_expr='import <nixpkgs> { system = builtins.currentSystem; }'
nixpkgs_path=$(find /nix/store -mindepth 1 -maxdepth 1 -name *-nixpkgs-* -type d)
nix-env \
--arg config "{ nix.package = ($nixpkgs_expr).nix; }" \
--arg pkgs "$nixpkgs_expr" \
--arg modulesPath 'throw "no modulesPath"' \
-f $nixpkgs_path/nixpkgs/nixos/modules/installer/tools/tools.nix \
-iA config.system.build.nixos-install
fi
)}
install-nix "$@"

View File

@ -0,0 +1,9 @@
#! /bin/sh
set -efu
install-nix-tools() {(
)}
install-nix-tools "$@"

View File

@ -0,0 +1,65 @@
#! /bin/sh
set -eux
{
umount /mnt/nix || [ $? -eq 32 ]
umount /mnt/boot || [ $? -eq 32 ]
umount /mnt/root || [ $? -eq 32 ]
umount /mnt || [ $? -eq 32 ]
umount /boot || [ $? -eq 32 ]
PATH=$(for i in /nix/store/*coreutils*/bin; do :; done; echo $i)
export PATH
mkdir /oldshit
mv /bin /oldshit/
mv /newshit/bin /
# TODO ensure /boot is empty
rmdir /newshit/boot
# skip /dev
rmdir /newshit/dev
mv /etc /oldshit/
mv /newshit/etc /
# skip /nix (it's already there)
rmdir /newshit/nix
# skip /proc
rmdir /newshit/proc
# skip /run
rmdir /newshit/run
# skip /sys
rmdir /newshit/sys
# skip /root
rmdir /newshit/root
# skip /tmp
# TODO rmdir /newshit/tmp
mv /home /oldshit/
mv /newshit/home /
mv /usr /oldshit/
mv /newshit/usr /
mv /var /oldshit/
mv /newshit/var /
mv /lib /oldshit/
mv /lib64 /oldshit/
mv /sbin /oldshit/
mv /srv /oldshit/
mv /opt /oldshit/
mv /newshit /root/ # TODO this one shoult be empty
mv /oldshit /root/
sync
}

View File

@ -67,7 +67,7 @@ types // rec {
options = {
config = mkOption {
type = str;
apply = _: ''
default = ''
${optionalString (net-config.via != null)
(concatMapStringsSep "\n" (a: "Address = ${a}") net-config.via.addrs)}
${concatMapStringsSep "\n" (a: "Subnet = ${a}") net-config.addrs}

View File

@ -1,4 +1,4 @@
{ stdenv, fetchgit, coreutils, curl, gnused, jq, ncurses, sshpass, ... }:
{ stdenv, fetchgit, coreutils, curl, gnused, inotifyTools, jq, ncurses, sshpass, ... }:
stdenv.mkDerivation {
name = "cac";
@ -20,6 +20,7 @@ stdenv.mkDerivation {
coreutils
curl
gnused
inotifyTools
jq
ncurses
sshpass

12
krebs/Zhosts/echelon Normal file
View File

@ -0,0 +1,12 @@
Address = 168.235.156.81
Subnet = 10.243.206.103
Subnet = 42:941e:2816:35f4:5c5e:206b:3f0b:f763
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA92ybhDahtGybpAkUNlG5Elxw05MVY4Pg7yK0dQugB4nVq+pnmi78
DOMeIciecMHmJM8n9UlUU0eWZVCgHeVd23d6J0hTHCv24p24uHEGGy7XlO/dPJ6A
IjROYU0l8c03pipdJ3cDBx6riArSglwmZJ7xH/Iw0BUhRZrPqbtijY7EcG2wc+8K
N9N9mBofVMl4EcBiDR/eecK+ro8OkeOmYPtYgFJLvxTYXiPIhOxMAlkOY2fpin/t
cgFLUFuN4ag751XjjcNpVovVq95vdg+VhKrrNVWZjJt03owW81BzoryY6CD2kIPq
UxK89zEdeYOUT7AxaT/5V5v41IvGFZxCzwIDAQAB
-----END RSA PUBLIC KEY-----

13
krebs/Zhosts/xu Normal file
View File

@ -0,0 +1,13 @@
Subnet = 10.243.13.38
Subnet = 42:0:0:0:0:0:0:1338
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAl3l7IWbfbkVgaJFM3s9g2UCh2rmqoTba16Of7NNWMj05L/hIkUsQ
uc43/QzidWh/4gEaq5MQ7JpLyzVBQYRJkNlPRF/Z07KdLBskAZCjDYdYue9BrziX
8s2Irs2+FNbCK2LqtrPhbcXQJvixsk6vjl2OBpWTDUcDEsk+D1YQilxdtyUzCUkw
mmRo/mzNsLZsYlSgZ6El/ZLkRdtexAzGxJ0DrukpDR0uqXXkp7jUaxRCZ+Cwanvj
4I1Hu5aHzWB7KJ1SIvpX3a4f+mun1gh3TPqWP5PUqJok1PSuScz6P2UGaLZZyH63
4o+9nGJPuzb9bpMVRaVGtKXd39jwY7mbqwIDAQAB
-----END RSA PUBLIC KEY-----

45
lass/1systems/echelon.nix Normal file
View File

@ -0,0 +1,45 @@
{ config, lib, pkgs, ... }:
let
inherit (import ../4lib { inherit pkgs lib; }) getDefaultGateway;
inherit (lib) head;
ip = (head config.krebs.hosts.echelon.nets.internet.addrs4);
in {
imports = [
../../tv/2configs/CAC-Developer-2.nix
../../tv/2configs/CAC-CentOS-7-64bit.nix
../2configs/base.nix
../2configs/retiolum.nix
{
networking.interfaces.enp2s1.ip4 = [
{
address = ip;
prefixLength = 24;
}
];
networking.defaultGateway = getDefaultGateway ip;
networking.nameservers = [
"8.8.8.8"
];
}
];
krebs.build = {
user = config.krebs.users.lass;
target = "root@${ip}";
host = config.krebs.hosts.echelon;
deps = {
secrets = {
url = "/home/lass/secrets/${config.krebs.build.host.name}";
};
stockholm = {
url = toString ../..;
};
};
};
networking.hostName = "echelon";
}

View File

@ -171,6 +171,7 @@
};
environment.systemPackages = with pkgs; [
cac
];
#TODO: fix this shit

View File

@ -16,7 +16,7 @@ with builtins;
users.extraUsers = {
root = {
openssh.authorizedKeys.keys = map readFile [
../../Zpubkeys/uriel.ssh.pub
../../krebs/Zpubkeys/uriel.ssh.pub
];
};
};

View File

@ -5,6 +5,7 @@ with lib;
imports = [
../3modules/iptables.nix
../2configs/vim.nix
../2configs/zsh.nix
{
users.extraUsers =
mapAttrs (_: h: { hashedPassword = h; })
@ -14,7 +15,7 @@ with lib;
users.extraUsers = {
root = {
openssh.authorizedKeys.keys = map readFile [
../../Zpubkeys/lass.ssh.pub
../../krebs/Zpubkeys/lass.ssh.pub
];
};
mainUser = {
@ -29,7 +30,7 @@ with lib;
"wheel"
];
openssh.authorizedKeys.keys = map readFile [
../../Zpubkeys/lass.ssh.pub
../../krebs/Zpubkeys/lass.ssh.pub
];
};
};
@ -42,7 +43,7 @@ with lib;
exim-retiolum.enable = true;
build.deps.nixpkgs = {
url = https://github.com/Lassulus/nixpkgs;
rev = "58a82ff50b8605b88a8f66481d8c85bf8ab53be3";
rev = "e74d0e7ff83c16846a81e1173543f180ad565076";
};
};
@ -147,4 +148,8 @@ with lib;
};
};
networking.dhcpcd.extraConfig = ''
noipv4ll
'';
}

View File

@ -4,7 +4,7 @@ let
inherit (import ../4lib { inherit pkgs lib; }) simpleScript;
mainUser = config.users.extraUsers.mainUser;
createBrowserUser = name: extraGroups: packages:
createChromiumUser = name: extraGroups: packages:
{
users.extraUsers = {
${name} = {
@ -26,16 +26,47 @@ let
];
};
createFirefoxUser = name: extraGroups: packages:
{
users.extraUsers = {
${name} = {
inherit name;
inherit extraGroups;
home = "/home/${name}";
useDefaultShell = true;
createHome = true;
};
};
lass.per-user.${name}.packages = packages;
security.sudo.extraConfig = ''
${mainUser.name} ALL=(${name}) NOPASSWD: ALL
'';
environment.systemPackages = [
(simpleScript name ''
sudo -u ${name} -i firefox $@
'')
];
};
#TODO: abstract this
in {
environment.systemPackages = [
(simpleScript "browser-select" ''
BROWSER=$(echo -e "ff\ncr\nfb\ngm\nflash" | dmenu)
$BROWSER $@
'')
];
imports = [
../3modules/per-user.nix
] ++ [
( createBrowserUser "ff" [ "audio" ] [ pkgs.firefox ] )
( createBrowserUser "cr" [ "audio" ] [ pkgs.chromium ] )
( createBrowserUser "fb" [ ] [ pkgs.chromium ] )
( createBrowserUser "gm" [ ] [ pkgs.chromium ] )
( createBrowserUser "flash" [ ] [ pkgs.flash ] )
( createFirefoxUser "ff" [ "audio" ] [ pkgs.firefox ] )
( createChromiumUser "cr" [ "audio" ] [ pkgs.chromium ] )
( createChromiumUser "fb" [ ] [ pkgs.chromium ] )
( createChromiumUser "gm" [ ] [ pkgs.chromium ] )
( createChromiumUser "flash" [ ] [ pkgs.flash ] )
];
nixpkgs.config.packageOverrides = pkgs : {

View File

@ -37,12 +37,12 @@ let
in {
environment.etc."chromium/policies/managed/master.json".source = pkgs.lib.mkForce masterPolicy;
environment.systemPackages = [
#pkgs.chromium
(pkgs.lib.overrideDerivation pkgs.chromium (attrs: {
buildCommand = attrs.buildCommand + ''
touch $out/TEST123
'';
}))
];
#environment.systemPackages = [
# #pkgs.chromium
# (pkgs.lib.overrideDerivation pkgs.chromium (attrs: {
# buildCommand = attrs.buildCommand + ''
# touch $out/TEST123
# '';
# }))
#];
}

View File

@ -58,6 +58,7 @@ in {
layout = "us";
xkbModel = "evdev";
xkbVariant = "altgr-intl";
xkbOptions = "caps:backspace";
};
}

View File

@ -17,7 +17,7 @@
krebs.retiolum = {
enable = true;
hosts = ../../Zhosts;
hosts = ../../krebs/Zhosts;
connectTo = [
"fastpoke"
"cloudkrebs"

View File

@ -16,15 +16,14 @@
environment.systemPackages = with pkgs; [
steam
];
networking.firewall = {
allowedUDPPorts = [
27031
27036
];
allowedTCPPorts = [
27036
27037
];
lass.iptables = {
tables = {
filter.INPUT.rules = [
{ predicate = "-p tcp --dport 27031"; target = "ACCEPT"; }
{ predicate = "-p tcp --dport 27036"; target = "ACCEPT"; }
{ predicate = "-p udp --dport 27031"; target = "ACCEPT"; }
{ predicate = "-p udp --dport 27036"; target = "ACCEPT"; }
];
};
};
}

View File

@ -4,7 +4,6 @@ let
mainUser = config.users.extraUsers.mainUser;
in {
virtualisation.virtualbox.host.enable = true;
users.extraUsers = {
virtual = {

126
lass/2configs/zsh.nix Normal file
View File

@ -0,0 +1,126 @@
{ config, lib, pkgs, ... }:
{
programs.zsh = {
enable = true;
shellInit = ''
#disable config wizard
zsh-newuser-install() { :; }
'';
interactiveShellInit = ''
HISTFILE=~/.histfile
HISTSIZE=1000000
SAVEHIST=100000
#unsetopt nomatch
setopt autocd extendedglob
bindkey -e
zstyle :compinstall filename '/home/lass/.zshrc'
#history magic
bindkey "" up-line-or-local-history
bindkey "" down-line-or-local-history
up-line-or-local-history() {
zle set-local-history 1
zle up-line-or-history
zle set-local-history 0
}
zle -N up-line-or-local-history
down-line-or-local-history() {
zle set-local-history 1
zle down-line-or-history
zle set-local-history 0
}
zle -N down-line-or-local-history
setopt share_history
setopt hist_ignore_dups
# setopt inc_append_history
bindkey '^R' history-incremental-search-backward
#C-x C-e open line in editor
autoload -z edit-command-line
zle -N edit-command-line
bindkey "^X^E" edit-command-line
#completion magic
fpath=(~/.zsh/completions $fpath)
autoload -Uz compinit
compinit
zstyle ':completion:*' menu select
#enable automatic rehashing of $PATH
zstyle ':completion:*' rehash true
#eval $( dircolors -b ~/.LS_COLORS )
#exports
export EDITOR='vim'
export MANPAGER='most'
export PAGER='vim -'
# export MANPAGER='sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | vim -R -c "set ft=man nonu nomod nolist" -'
#beautiful colors
alias ls='ls --color'
zstyle ':completion:*:default' list-colors ''${(s.:.)LS_COLORS}
#emacs bindings
bindkey "[7~" beginning-of-line
bindkey "[8~" end-of-line
bindkey "Oc" emacs-forward-word
bindkey "Od" emacs-backward-word
#aliases
alias ll='ls -l'
alias la='ls -la'
alias pinginet='ping 8.8.8.8'
alias du='du -hd1'
alias qiv="qiv -f -m"
alias zshres="source ~/.zshrc"
#fancy window title magic
case $TERM in
(*xterm* | *rxvt*)
# Write some info to terminal title.
# This is seen when the shell prompts for input.
function precmd {
print -Pn "\e]0;%(1j,%j job%(2j|s|); ,)%~\a"
}
# Write command and args to terminal title.
# This is seen while the shell waits for a command to complete.
function preexec {
printf "\033]0;%s\a" "$1"
}
;;
esac
'';
promptInit = ''
autoload -U promptinit
promptinit
error='%(?..%F{red}%?%f )'
case $UID in
0)
username='%F{red}root%f'
;;
1337)
username=""
;;
*)
username='%F{blue}%n%f'
;;
esac
if test -n "$SSH_CLIENT"; then
PROMPT="$error$username@%F{magenta}%M%f %~ "
else
PROMPT="$error$username %~ "
fi
'';
};
users.defaultUserShell = "/run/current-system/sw/bin/zsh";
}

View File

@ -17,4 +17,8 @@ krebs // rec {
ln -s ${pkgs.writeScript name content} $out/bin/${name}
'';
};
getDefaultGateway = ip:
concatStringsSep "." (take 3 (splitString "." ip) ++ ["1"]);
}

View File

@ -2,10 +2,8 @@
let
inherit (pkgs) callPackage;
kpkgs = import ../../krebs/5pkgs { inherit pkgs; };
in
kpkgs //
rec {
bitlbee-dev = callPackage ./bitlbee-dev.nix {};
bitlbee-steam = callPackage ./bitlbee-steam.nix { inherit bitlbee-dev; };