aboutsummaryrefslogtreecommitdiff
path: root/pkgs/xinclude2nix
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2018-12-11 18:10:48 +0300
committerIgor Pashev <pashev.igor@gmail.com>2018-12-11 18:10:48 +0300
commit8b0968b2054d3bb8d90b5ac056727f7c2ebeaed3 (patch)
treed03b70f693463fc836a8dbe4240424d2547530c8 /pkgs/xinclude2nix
parentc4273035cf5876e3ba8ed2c6b492d31c2de290ee (diff)
downloadnixsap-8b0968b2054d3bb8d90b5ac056727f7c2ebeaed3.tar.gz
(* HUGE *) Use nixpkgs overlays
Diffstat (limited to 'pkgs/xinclude2nix')
-rw-r--r--pkgs/xinclude2nix/default.nix60
-rw-r--r--pkgs/xinclude2nix/xinclude2nix.hs49
2 files changed, 109 insertions, 0 deletions
diff --git a/pkgs/xinclude2nix/default.nix b/pkgs/xinclude2nix/default.nix
new file mode 100644
index 0000000..09a9ab3
--- /dev/null
+++ b/pkgs/xinclude2nix/default.nix
@@ -0,0 +1,60 @@
+{ runCommand, haskellPackages }:
+
+/*
+ Given a list of XML files, produces a Nix file with a list of files included
+ with the XInclude mechanism. The file produced can be imported into other
+ Nix files. This requires read-write mode of evaluation.
+
+ Use case: XML config files with portions of sensitive data (secrets, keys),
+ merged in runtime. With this package, deployment tools like NixOps can be
+ taught to extract keys and deploy them automatically.
+
+
+ Example of input file (for Jenkins):
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <hudson xmlns:xi="http://www.w3.org/2001/XInclude">
+ <useSecurity>true</useSecurity>
+ <authorizationStrategy class="hudson.security.ProjectMatrixAuthorizationStrategy">
+ <permission>hudson.model.Hudson.Read:ip1981</permission>
+ <permission>hudson.model.Item.Build:ip1981</permission>
+ <permission>hudson.model.Item.Cancel:ip1981</permission>
+ <permission>hudson.model.Item.Read:ip1981</permission>
+ <permission>hudson.model.Hudson.Administer:ip1981</permission>
+ </authorizationStrategy>
+ <securityRealm class="org.jenkinsci.plugins.GithubSecurityRealm">
+ <clientID>XXXXXXXXXXXXXXXXXXX</clientID>
+ <xi:include href="/run/keys/github-oauth-XXXXXXXXXXXXXXXXXXX.xml"/>
+ <oauthScopes>read:org,user:email</oauthScopes>
+ </securityRealm>
+ </hudson>
+
+
+ Corresponding output file (/nix/store/abc...xyz-xinclude.nix):
+
+ ["/run/keys/github-oauth-XXXXXXXXXXXXXXXXXXX.xml"]
+
+*/
+
+# XXX: either string or list of strings
+xmlFiles:
+
+let
+
+ inherit (builtins) toString;
+
+ xinclude2nix =
+ let
+ deps = hpkgs: with hpkgs; [ hxt ];
+ ghc = "${haskellPackages.ghcWithPackages deps}/bin/ghc -Wall -static";
+ in runCommand "xinclude2nix" {} ''
+ ${ghc} -o $out ${./xinclude2nix.hs}
+ '';
+
+in runCommand "xinclude.nix" {} ''
+ echo ${xinclude2nix} ${toString xmlFiles} >&2
+ ${xinclude2nix} ${toString xmlFiles} > $out
+ echo -n "$out: " >&2
+ cat "$out" >&2
+''
+
diff --git a/pkgs/xinclude2nix/xinclude2nix.hs b/pkgs/xinclude2nix/xinclude2nix.hs
new file mode 100644
index 0000000..369f103
--- /dev/null
+++ b/pkgs/xinclude2nix/xinclude2nix.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE Arrows #-}
+
+{-
+ Takes a list of XML files
+ Parses them for xi:xinclude elements
+ Extract included files
+ Prints list of included files
+-}
+module Main
+ ( main
+ ) where
+
+import Data.List (isPrefixOf, stripPrefix)
+import Data.Maybe (fromMaybe)
+import System.Environment (getArgs)
+import Text.XML.HXT.Core
+ ((>>>), deep, getAttrValue, hasAttr, hasName, isElem, readDocument,
+ returnA, runX)
+
+getXIncludes :: FilePath -> IO [String]
+getXIncludes xmlFileName =
+ runX $
+ readDocument [] xmlFileName >>>
+ deep (isElem >>> hasName "xi:include" >>> hasAttr "href") >>>
+ proc d ->
+ do href <- getAttrValue "href" -< d
+ returnA -< href
+
+getFiles :: [String] -> [String]
+getFiles = map stripScheme . filter isFile
+ where
+ fileScheme = "file://"
+ isFile s = "/" `isPrefixOf` s || (fileScheme `isPrefixOf` s)
+ stripScheme u = fromMaybe u (stripPrefix fileScheme u)
+
+unique :: [String] -> [String]
+unique [] = []
+unique (x:xs)
+ | x `elem` xs = unique xs
+ | otherwise = x : unique xs
+
+toNix :: [String] -> String
+toNix ss = "[" ++ unwords (map show ss) ++ "]"
+
+main :: IO ()
+main = do
+ paths <- getArgs
+ includedFiles <- unique . getFiles . concat <$> mapM getXIncludes paths
+ putStrLn $ toNix includedFiles