From c41b14e269dd6a88a627c4e4586b0aa1e79ee4e6 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 11 Jun 2017 10:23:15 -0500 Subject: [PATCH] Fixing docker2nix's Nix expression output (#4) * Making docker2nix's output more idiomatic * Updating the READMEs --- README.md | 17 ++-- docker2nix/README.md | 11 ++- src/Data/Docker/Nix/FetchDocker.hs | 124 +++++++++++++---------------- test/data/golden-debian:jessie.nix | 11 ++- 4 files changed, 74 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 58f02c8..40ee254 100644 --- a/README.md +++ b/README.md @@ -62,26 +62,25 @@ Next, we can easily generate a `fetchdocker` derivation using `docker2nix`: ```shell $ hocker-manifest library/debian jessie | docker2nix library/debian jessie -{ - config.docker.images.debian = pkgs.fetchdocker { +{ fetchDockerConfig, fetchDockerLayer, fetchdocker }: +fetchdocker { name = "debian"; registry = "https://registry-1.docker.io/v2/"; repository = "library"; imageName = "debian"; tag = "jessie"; - imageConfig = pkgs.fetchDockerConfig { + imageConfig = fetchDockerConfig { inherit registry repository imageName tag; - sha256 = "1viqbygsz9547jy830f2lk2hcrxjf7gl9h1xda9ws5kap8yw50ry"; + sha256 = "1rwinmvfc8jxn54y7qnj82acrc97y7xcnn22zaz67y76n4wbwjh5"; }; imageLayers = let - layer0 = pkgs.fetchDockerLayer { + layer0 = fetchDockerLayer { inherit registry repository imageName tag; - layerDigest = "10a267c67f423630f3afe5e04bbbc93d578861ddcc54283526222f3ad5e895b9"; - sha256 = "1fcmx3aklbr24qsjhm6cvmhqhmrxr6xlpq75mzrk0dj2gz36g8hh"; + layerDigest = "cd0a524342efac6edff500c17e625735bbe479c926439b263bbe3c8518a0849c"; + sha256 = "1744l0c8ag5y7ck9nhr6r5wy9frmaxi7xh80ypgnxb7g891m42nd"; }; in [ layer0 ]; - }; -} + } ``` ## Private Registries diff --git a/docker2nix/README.md b/docker2nix/README.md index 532ccb3..18e1fb7 100644 --- a/docker2nix/README.md +++ b/docker2nix/README.md @@ -30,26 +30,25 @@ JSON retrieved by `hocker-manifest`: ```shell $ hocker-manifest library/debian jessie | docker2nix library/debian jessie -{ - config.docker.images.debian = pkgs.fetchdocker { +{ fetchDockerConfig, fetchDockerLayer, fetchdocker }: +fetchdocker { name = "debian"; registry = "https://registry-1.docker.io/v2/"; repository = "library"; imageName = "debian"; tag = "jessie"; - imageConfig = pkgs.fetchDockerConfig { + imageConfig = fetchDockerConfig { inherit registry repository imageName tag; sha256 = "1rwinmvfc8jxn54y7qnj82acrc97y7xcnn22zaz67y76n4wbwjh5"; }; imageLayers = let - layer0 = pkgs.fetchDockerLayer { + layer0 = fetchDockerLayer { inherit registry repository imageName tag; layerDigest = "cd0a524342efac6edff500c17e625735bbe479c926439b263bbe3c8518a0849c"; sha256 = "1744l0c8ag5y7ck9nhr6r5wy9frmaxi7xh80ypgnxb7g891m42nd"; }; in [ layer0 ]; - }; -} + } ``` And to load a fetched docker image into a running docker daemon on a NixOS diff --git a/src/Data/Docker/Nix/FetchDocker.hs b/src/Data/Docker/Nix/FetchDocker.hs index 51319fc..d9fac96 100644 --- a/src/Data/Docker/Nix/FetchDocker.hs +++ b/src/Data/Docker/Nix/FetchDocker.hs @@ -39,25 +39,24 @@ import Types.Exceptions import Types.ImageTag {- Example output of the pretty-printed, generated Nix expression AST. -{ - config.docker.images.debian = pkgs.fetchdocker { - name = "debian"; - registry = "https://registry-1.docker.io/v2/"; - repository = "library"; - imageName = "debian"; - tag = "latest"; - imageConfig = pkgs.fetchDockerConfig { - inherit registry repository imageName tag; - sha256 = "1viqbygsz9547jy830f2lk2hcrxjf7gl9h1xda9ws5kap8yw50ry"; - }; - imageLayers = let - layer0 = pkgs.fetchDockerLayer { - inherit registry repository imageName tag; - layerDigest = "10a267c67f423630f3afe5e04bbbc93d578861ddcc54283526222f3ad5e895b9"; - sha256 = "1fcmx3aklbr24qsjhm6cvmhqhmrxr6xlpq75mzrk0dj2gz36g8hh"; - }; - in [ layer0 ]; +{ fetchdocker, fetchDockerConfig, fetchDockerLayer }: +fetchdocker { + name = "debian"; + registry = "https://registry-1.docker.io/v2/"; + repository = "library"; + imageName = "debian"; + tag = "latest"; + imageConfig = fetchDockerConfig { + inherit registry repository imageName tag; + sha256 = "1viqbygsz9547jy830f2lk2hcrxjf7gl9h1xda9ws5kap8yw50ry"; }; + imageLayers = let + layer0 = fetchDockerLayer { + inherit registry repository imageName tag; + layerDigest = "10a267c67f423630f3afe5e04bbbc93d578861ddcc54283526222f3ad5e895b9"; + sha256 = "1fcmx3aklbr24qsjhm6cvmhqhmrxr6xlpq75mzrk0dj2gz36g8hh"; + }; + in [ layer0 ]; } -} @@ -105,64 +104,58 @@ record, a config digest, and a list of layer digests. The generated AST, pretty-printed, may look similar to the following: @ -{ - config.docker.images.debian = pkgs.fetchdocker { - name = "debian"; - registry = "https://registry-1.docker.io/v2/"; - repository = "library"; - imageName = "debian"; - tag = "latest"; - imageConfig = pkgs.fetchDockerConfig { - inherit registry repository imageName tag; - sha256 = "1viqbygsz9547jy830f2lk2hcrxjf7gl9h1xda9ws5kap8yw50ry"; - }; - imageLayers = let - layer0 = pkgs.fetchDockerLayer { - inherit registry repository imageName tag; - layerDigest = "10a267c67f423630f3afe5e04bbbc93d578861ddcc54283526222f3ad5e895b9"; - sha256 = "1fcmx3aklbr24qsjhm6cvmhqhmrxr6xlpq75mzrk0dj2gz36g8hh"; - }; - in [ layer0 ]; +{ fetchdocker, fetchDockerConfig, fetchDockerLayer }: +fetchdocker { + name = "debian"; + registry = "https://registry-1.docker.io/v2/"; + repository = "library"; + imageName = "debian"; + tag = "latest"; + imageConfig = fetchDockerConfig { + inherit registry repository imageName tag; + sha256 = "1viqbygsz9547jy830f2lk2hcrxjf7gl9h1xda9ws5kap8yw50ry"; }; + imageLayers = let + layer0 = fetchDockerLayer { + inherit registry repository imageName tag; + layerDigest = "10a267c67f423630f3afe5e04bbbc93d578861ddcc54283526222f3ad5e895b9"; + sha256 = "1fcmx3aklbr24qsjhm6cvmhqhmrxr6xlpq75mzrk0dj2gz36g8hh"; + }; + in [ layer0 ]; } @ -} generateFetchDockerExpr :: HockerImageMeta -> ConfigDigest -> [(Base16Digest, Base32Digest)] -> Either HockerException NExpr generateFetchDockerExpr dim@HockerImageMeta{..} configDigest layerDigests = do - let fetchconfig = mkFetchDockerConfig commonInherits configDigest - fetchlayers = - mkLets - (mkFetchDockerLayers commonInherits layerDigests) - (mkList $ fmap genLayerId [0..(Prelude.length layerDigests)-1]) - - fetchDockerExpr <- mkFetchDocker dim fetchconfig fetchlayers - - pure (Fix $ NSet [ dockerImgExpr fetchDockerExpr ]) - - where - dockerImgExpr fDockerExpr = NamedVar imgSelector fDockerExpr - genLayerId i = mkSym . T.pack $ "layer" <> show i - imgSelector = - [ StaticKey "config" - , StaticKey "docker" - , StaticKey "images" - , StaticKey imageName - ] - commonInherits = inherit + let commonInherits = inherit [ StaticKey "registry" , StaticKey "repository" , StaticKey "imageName" , StaticKey "tag" ] + let genLayerId i = mkSym . T.pack $ "layer" <> show i + let fetchconfig = mkFetchDockerConfig commonInherits configDigest + fetchlayers = + mkLets + (mkFetchDockerLayers commonInherits layerDigests) + (mkList $ fmap genLayerId [0..(Prelude.length layerDigests)-1]) + fetchDockerExpr <- mkFetchDocker dim fetchconfig fetchlayers + pure + (mkFunction + (mkParamset + [ ("fetchdocker", Nothing) + , ("fetchDockerConfig", Nothing) + , ("fetchDockerLayer", Nothing) + ]) fetchDockerExpr) --- | Generate a @pkgs.fetchdocker { ... }@ function call and argument +-- | Generate a @fetchdocker { ... }@ function call and argument -- attribute set. Please see 'generateNixExprs' documentation for an -- example of full output. mkFetchDocker :: HockerImageMeta -> NExpr -> NExpr -> Either HockerException NExpr mkFetchDocker HockerImageMeta{..} fetchconfig fetchlayers = do registry <- Bifunctor.first mkHockerException serializedRegistry pure - (mkApp (mkPkgsAttrSelector constFetchdocker) + (mkApp (mkSym constFetchdocker) (attrsE [ ("name", mkStr $ fromMaybe imageName altImageName) , ("registry", mkStr registry) @@ -180,17 +173,17 @@ mkFetchDocker HockerImageMeta{..} fetchconfig fetchlayers = do HockerException (show err) Nothing Nothing --- | Generate a @pkgs.fetchDockerConfig { ... }@ function call and +-- | Generate a @fetchDockerConfig { ... }@ function call and -- argument attrset. This function takes an argument for a list of -- static keys to inherit from the parent attribute set; it helps -- reduce the noise in the output expression. mkFetchDockerConfig :: Binding NExpr -> Base32Digest -> NExpr mkFetchDockerConfig inherits (Base32Digest digest) = - mkApp (mkPkgsAttrSelector constFetchDockerConfig) + mkApp (mkSym constFetchDockerConfig) (Fix $ NSet [ inherits, "sha256" $= (mkStr digest) ]) -- | Generate a list of Nix expression ASTs representing --- @pkgs.fetchDockerLayer { ... }@ function calls. This function takes +-- @fetchDockerLayer { ... }@ function calls. This function takes -- an argument for a list of static keys to inherit from the parent -- attribute set; it helps reduce the noise in the output expression. -- @@ -202,7 +195,7 @@ mkFetchDockerConfig inherits (Base32Digest digest) = -- pre-computed hash (which we have, thanks to the manifest) and the -- hash must be base32 encoded using @nix-hash@'s own base32 -- encoding. The base16 encoded hash digest is needed intact in order --- for the @pkgs.fetchDockerLayer@ builder script (which calls the +-- for the @fetchDockerLayer@ builder script (which calls the -- @hocker-layer@ utility) to download the layer from a docker -- registry. mkFetchDockerLayers :: Binding NExpr -> [(Base16Digest, Base32Digest)] -> [Binding NExpr] @@ -211,14 +204,9 @@ mkFetchDockerLayers inherits layerDigests = where mkLayerId i = T.pack $ "layer" <> show i mkFetchLayer (i, ((Base16Digest d16), (Base32Digest d32))) = - (mkLayerId i) $= mkApp (mkPkgsAttrSelector constFetchDockerLayer) + (mkLayerId i) $= mkApp (mkSym constFetchDockerLayer) (Fix $ NSet [ inherits , "layerDigest" $= (mkStr d16) -- Required in order to perform a registry request , "sha256" $= (mkStr d32) -- Required by Nix for fixed output derivations ]) - --- | Generate a selector for an attribute within the @pkgs@ set; i.e --- @pkgs.fetchDockerLayer@. -mkPkgsAttrSelector :: T.Text -> NExpr -mkPkgsAttrSelector k = Fix $ NSelect (mkSym "pkgs") [StaticKey k] Nothing diff --git a/test/data/golden-debian:jessie.nix b/test/data/golden-debian:jessie.nix index 3ce46a3..0234bbc 100644 --- a/test/data/golden-debian:jessie.nix +++ b/test/data/golden-debian:jessie.nix @@ -1,20 +1,19 @@ -{ - config.docker.images.debian = pkgs.fetchdocker { +{ fetchDockerConfig, fetchDockerLayer, fetchdocker }: +fetchdocker { name = "debian"; registry = "https://registry-1.docker.io/v2/"; repository = "library"; imageName = "debian"; tag = "jessie"; - imageConfig = pkgs.fetchDockerConfig { + imageConfig = fetchDockerConfig { inherit registry repository imageName tag; sha256 = "1rwinmvfc8jxn54y7qnj82acrc97y7xcnn22zaz67y76n4wbwjh5"; }; imageLayers = let - layer0 = pkgs.fetchDockerLayer { + layer0 = fetchDockerLayer { inherit registry repository imageName tag; layerDigest = "cd0a524342efac6edff500c17e625735bbe479c926439b263bbe3c8518a0849c"; sha256 = "1744l0c8ag5y7ck9nhr6r5wy9frmaxi7xh80ypgnxb7g891m42nd"; }; in [ layer0 ]; - }; -} \ No newline at end of file + } \ No newline at end of file