-
Notifications
You must be signed in to change notification settings - Fork 47
Open
Labels
💪 Effort: 3This issue is of medium complexity or only partly well understoodThis issue is of medium complexity or only partly well understood🆗 Status: AcceptedThis issue has been acceptedThis issue has been accepted
Description
Fixed in #331
I have a pretty standard poetry2nix web application that I wrap on its environment derivation using hypercorn
. The built OCI fails to detect the correct binary location because it relies on lib.getExe
. mkOperable
works as expected, though.
Symptoms
I don't have the exact error that throws from Docker engine. It should be something along the line of Docker container not being to start up because /bin/entrypoint
not found.
If you have access to ls
(I use Python's os.listdir
because I'm too lazy to build a dev layer), You would see that /bin/entrypoint
exists, but it is a broken symlink.
$ std //ops/oci/p2n-env-oci:load
docker-daemon:<image>:<hash>
$ docker run -it --rm --entrypoint /bin/sh <image>:<hash>
$ python3
import os
def follow_symlinks(path):
if os.path.islink(path):
link_path = os.readlink(path)
print(f'{path} -> {link_path}')
return follow_symlinks(link_path)
elif os.path.exists(path):
print(f'Path is a real file or directory: {path}')
return path
else:
print(f'Path not found: {path}')
return None
follow_symlinks('/bin/entrypoint')
One example output is
/bin/entrypoint -> /nix/store/<hash>-oci-setup-links/bin/entrypoint
/nix/store/<hash>-oci-setup-links/bin/entrypoint -> /nix/store/<hash>-operable-python3-3.10.11-env/bin/operable-python3
Path not found: /nix/store/<hash>-operable-python3-3.10.11-env/bin/operable-python3
>>> os.listdir('/nix/store/<hash>-operable-python3-3.10.11-env/bin/')
["operable-python3-3.10.11-env"]
Workaround
p2n-env-fix = workspace_app.dependencyEnv.overrideAttrs (prev: {
# HACK: This allows mkOperable and mkStandardOCI to resolve symlink correctly
name = "p2n-env-fix";
meta.mainProgram = "python3";
});
Nix flakes and its workaround variant
# nix/dev/packages/tools.nix
{
inputs,
cell,
}: let
system = inputs.nixpkgs.system;
poetry2nix = inputs.nix-boost.pkgs.${system}.mypkgs.poetry2nix;
workspace_root = "${inputs.self}";
workspace_app = poetry2nix.mkPoetryApplication {
projectDir = workspace_root;
};
in {
p2n-env = workspace_app.dependencyEnv;
p2n-env-fix = workspace_app.dependencyEnv.overrideAttrs (prev: {
# HACK: This allows mkOperable and mkStandardOCI to resolve symlink correctly
name = "p2n-env-fix";
meta.mainProgram = "python3";
});
frontend = {}; # omitted
}
# nix/ops/exe.nix
{
inputs,
cell,
}: let
inherit (inputs.std.lib) ops;
runtimeScript = ''
hypercorn my.backend:app --bind '0.0.0.0:10140' --worker-class uvloop
'';
runtimeEnv = {
DIST_LOC = "${inputs.cells.dev.packages.frontend}/dist";
};
in {
p2n-env-ops = ops.mkOperable {
package = inputs.cells.dev.packages.p2n-env;
runtimeInputs = [
inputs.cells.dev.packages.p2n-env
inputs.cells.dev.packages.frontend
];
inherit runtimeScript runtimeEnv;
};
p2n-env-fix-ops = ops.mkOperable {
package = inputs.cells.dev.packages.p2n-env-fix;
runtimeInputs = [
inputs.cells.dev.packages.p2n-env-fix
inputs.cells.dev.packages.frontend
];
inherit runtimeScript runtimeEnv;
};
}
# nix/ops/oci.nix
{
inputs,
cell,
}: let
inherit (inputs.std.lib) ops;
pyproject = builtins.fromTOML (builtins.readFile "${inputs.self}/pyproject.toml");
ws-authors = pyproject.tool.poetry.authors;
in {
p2n-env-oci = ops.mkStandardOCI {
name = "p2n-env-oci";
# NOTE: swap to p2n-env-fix-ops fixes it
operable = inputs.cells.ops.exe.p2n-env-ops;
meta = {
# NOTE: unfair, std doesn't allow me to give more tags :(
# including this and `nix` and `std` tells me to remove either `meta.tags` or `tag`
# tags = ["ops-latest" "ops-${ws-version}" "${ws-name}-${ws-version}"];
};
config = {
ExposedPorts."10140/tcp" = {};
Volumes = {
# For secrets and env
"/var/run" = {};
};
Env = [
"ENV_PATH=/var/run/.env"
"GNMI_CONFIG_LOC=/var/run/.config.yml"
];
Labels."org.opencontainers.image.title" = "p2n-env";
Labels."org.opencontainers.image.authors" = builtins.concatStringsSep ", " ws-authors;
};
};
# Currently, there is no good documented way to publish to arbitrary repositories at once
# NOTE: untested
p2n-env-gl = cell.oci.p2n-env-oci.overrideAttrs {
meta.repo = "gitlab.<domain>.com/<group>/<repo>/<image>";
};
}
Some more insights from build artifacts
nix-repl> packages.aarch64-darwin.p2n-env.name
"python3-3.10.11-env"
nix-repl> packages.aarch64-darwin.p2n-env.meta.name
"python3-3.10.11"
nix-repl> lib.getExe packages.aarch64-darwin.p2n-env-ops
"/nix/store/<hash>-operable-python3-3.10.11-env/bin/operable-python3"
Thoughts
- poetry2nix recommends using dependencyEnv when working with ASGI runtime like hypercorn, but I have yet to try this with
mkPoetryEnv
.mkPoetryEnv
does provide a simple way to override onto a simplername
, whereas withdependencyEnv
overwrites the declaredname
. - Nevertheless, this case should be considered in general for packages that may have rough edges in its name.
Requests
- Resolve this issue along with Straightforward example implementing operables/containers? #299 by adding minimal build recipes along with troubleshoots
- There is a bit of rough edges mentioned in the provided workspace for Improve container actions #251 in the case of tags
- Add check phase for
mkStandardOCI
that checks for symlink integrity. Might be doable at the phase of writing/bin/entrypoint
and before usingnix2container
to write.json
manifest
Metadata
Metadata
Assignees
Labels
💪 Effort: 3This issue is of medium complexity or only partly well understoodThis issue is of medium complexity or only partly well understood🆗 Status: AcceptedThis issue has been acceptedThis issue has been accepted