Skip to content

Instantly share code, notes, and snippets.

@jb55
Last active July 30, 2023 21:45
Show Gist options
  • Save jb55/b8b49893e18b61fb8c3ea3c924358278 to your computer and use it in GitHub Desktop.
Save jb55/b8b49893e18b61fb8c3ea3c924358278 to your computer and use it in GitHub Desktop.
deploy dotnet core apps on nixos
{ stdenv, lib, bash, callPackage, writeText, makeWrapper, writeScript, dotnet-sdk,
patchelf, libunwind, coreclr, libuuid, curl, zlib, icu }:
let
config = "Staging";
project = "RazorCx.Api";
target = "linux-x64";
rpath = stdenv.lib.makeLibraryPath [ libunwind coreclr libuuid stdenv.cc.cc curl zlib icu ];
nuget-pkg-json = lib.importJSON ./nuget-packages.json;
other-pkg-json = lib.importJSON ./other-packages.json;
fetchNuGet = callPackage ./nix/fetchnuget {};
make-nuget-pkg = pkgjson: {
package = fetchNuGet pkgjson;
meta = pkgjson;
};
make-nuget-pkgset = callPackage ./nix/make-nuget-packageset {};
nuget-pkgs = map make-nuget-pkg (nuget-pkg-json ++ other-pkg-json);
nuget-pkg-dir = make-nuget-pkgset "${project}-nuget-pkgs" nuget-pkgs;
nuget-config = writeText "nuget.config" ''
<configuration>
<packageSources>
<clear />
<add key="local" value="${nuget-pkg-dir}" />
</packageSources>
</configuration>
'';
runtime-config = writeText "runtimeconfig.json" ''
{
"runtimeOptions": {
"additionalProbingPaths": [
"${nuget-pkg-dir}"
]
}
}
'';
in
stdenv.mkDerivation rec {
baseName = "${project}";
version = "2018-05-03";
name = "${baseName}-${config}-${version}";
src = lib.sourceFilesBySuffices ./. [
".cs"
".props"
".projitems"
".config"
".csproj"
"appsettings.${config}.json"
"appsettings.json"
".html"
".sln"
];
buildInputs = [ dotnet-sdk makeWrapper patchelf ];
configurePhase = ''
cp ${nuget-config} nuget.config
'';
patchPhase = ''
# shouldn't need tools
sed -i '/DotNetCliToolReference/d' RazorCx.Api/RazorCx.Api.csproj
sed -i '/DotNetCliToolReference/d' RazorCx.EntityFrameworkCore/RazorCx.EntityFrameworkCore.csproj
sed -i '/DotNetCliToolReference/d' RazorCx.Core/RazorCx.Core.csproj
'';
buildPhase = ''
printf "\n\n\n%s\n\n\n" "${nuget-pkg-dir}"
tmp="$(mktemp -d)"
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
export DOTNET_CLI_TELEMETRY_OPTOUT=1
export HOME="$tmp"
dotnet publish -r ${target} --source ${nuget-pkg-dir} -c ${config} ${project}
'';
installPhase = ''
mkdir -p $out
cp -r ${project}/bin/${config}/netcoreapp2.0/${target}/publish $out/bin
cp ${runtime-config} $out/bin/${project}.runtimeconfig.json
cp -r ${project}/Properties $out/bin
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$out/bin/${project}"
patchelf --set-rpath "${rpath}" "$out/bin/${project}"
wrapProgram "$out/bin/${project}" \
--prefix LD_LIBRARY_PATH : ${rpath}
find $out/bin -type f -name "*.so" -exec patchelf --set-rpath "${rpath}" {} \;
mv $out/bin/${project} $out/bin/${project}-${config}
sed -i s/.${project}-wrapped/${project}/g $out/bin/${project}-${config}
mv $out/bin/.${project}-wrapped $out/bin/${project}
'';
dontStrip = true;
meta = with stdenv.lib; {
description = "Artificial Intelligence for Steel Detailing";
homepage = "https://razorcx.com";
license = licenses.unfree;
maintainers = [ maintainers.jb55 ];
platforms = with platforms; linux;
};
}
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
function filterFile(file) {
return !( file.endsWith(".nuspec")
|| file.endsWith(".txt")
)
}
function usage () {
console.error("usage: ./deps-to-nix project/obj/project.assets.json")
process.exit(1)
}
function loadLibraries(file) {
let json = JSON.parse(fs.readFileSync(file));
return Object.keys(json.libraries).reduce((obj, key) => {
let lib = json.libraries[key]
if (lib.type === 'project') {
let otherProj = path.dirname(lib.path)
try {
let otherAssets = path.join(otherProj, "obj/project.assets.json")
let otherJson = loadLibraries(otherAssets)
Object.assign(otherJson, obj)
}
catch (e) {
//console.error(e)
}
return obj
}
else {
obj[key] = lib
}
return obj
}, {})
}
if (process.argv.length < 3)
usage()
let libraries = loadLibraries(process.argv[2]);
let pkgs = []
for (let key in libraries) {
let lib = libraries[key]
let [name, ver] = key.split('/')
let sha512 = new Buffer(lib.sha512, 'base64').toString('hex')
pkgs.push({
baseName: name,
version: ver,
sha512: sha512,
path: lib.path,
outputFiles: lib.files.filter(filterFile)
})
}
console.log(JSON.stringify(pkgs, null, 4))
{ stdenvNoCC, lib, fetchurl, unzip, xxd }:
attrs @
{ baseName
, version
, outputFiles
, url ? "https://www.nuget.org/api/v2/package/${baseName}/${version}"
, sha512 ? ""
, md5 ? ""
, ...
}:
if md5 != "" then
throw "fetchnuget does not support md5 anymore, please use sha256"
else
let
arrayToShell = (a: toString (map (lib.escape (lib.stringToCharacters "\\ ';$`()|<>\t") ) a));
make-cp = outFile: ''
outFile="${outFile}"
[[ ''${outFile: -7} == ".sha512" ]] && echo -n "${sha512}" \
| ${lib.getBin xxd}/bin/xxd -r -p \
| base64 -w500 > ${outFile}
cp -r --parents -t $out "${outFile}" || :
'';
nupkg-name = lib.strings.toLower "${baseName}.${version}.nupkg";
in
stdenvNoCC.mkDerivation ({
name = "${baseName}-${version}";
src = fetchurl {
inherit url sha512;
name = "${baseName}.${version}.zip";
};
sourceRoot = ".";
buildInputs = [ unzip ];
dontStrip = true;
installPhase = ''
mkdir -p $out
chmod +r *.nuspec
cp *.nuspec $out
cp $src $out/${nupkg-name}
${lib.strings.concatStringsSep "\n" (map make-cp outputFiles)}
'';
# not sure if this necessary
preInstall = ''
# function traverseRename () {
# for e in *
# do
# t="$(echo "$e" | sed -e "s/%20/\ /g" -e "s/%2B/+/g")"
# [ "$t" != "$e" ] && mv -vn "$e" "$t"
# if [ -d "$t" ]
# then
# cd "$t"
# traverseRename
# cd ..
# fi
# done
# }
# traverseRename
'';
} // attrs)
{ lndir, runCommand, lib }:
name: pkgs:
let
args = {
preferLocalBuild = true;
allowSubstitutes = false;
inherit name;
};
make-cmd = pkg: ''
mkdir -p $out/${pkg.meta.path}
${lndir}/bin/lndir -silent "${pkg.package}" "$out/${pkg.meta.path}"
'';
in runCommand name args
''
${lib.strings.concatStringsSep "\n" (map make-cmd pkgs)}
''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment