Packaging Oracle Database 23c

Hello,

I’m trying to create a derivation for Oracle database 23c. The package provided by Oracle is an RPM file, can be freely downloaded from Oracle without registration.

I’ve started a draft package for nixpkgs, published in a temporary flake at https://github.com/drupol/nix-oracle-db/blob/7bd7c4408a8f4cd1786def443295c1f0b36cd155/packages/oracledb.nix

However, when I try to run one of the binaries, I get:

❯ ./result/opt/oracle/product/23c/dbhomeFree/bin/sqlplus
fish: Job 1, './result/opt/oracle/product/23c…' terminated by signal SIGSEGV (Address boundary error)

When I run ldd on it:

❯ ldd ./result/opt/oracle/product/23c/dbhomeFree/bin/sqlplus 
        linux-vdso.so.1 (0x00007fff7e088000)
        libsqlplus.so => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/libsqlplus.so (0x00007f10de3e4000)
        libclntsh.so.23.1 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/libclntsh.so.23.1 (0x00007f10d9600000)
        libclntshcore.so.23.1 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/libclntshcore.so.23.1 (0x00007f10d9200000)
        libnnz.so => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/libnnz.so (0x00007f10d8a00000)
        libdl.so.2 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/libdl.so.2 (0x00007f10d8600000)
        libm.so.6 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/libm.so.6 (0x00007f10d8200000)
        libpthread.so.0 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/libpthread.so.0 (0x00007f10d7e00000)
        librt.so.1 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/librt.so.1 (0x00007f10d7a00000)
        libaio.so.1 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/libaio.so.1 (0x00007f10d7600000)
        libresolv.so.2 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/libresolv.so.2 (0x00007f10d7200000)
        libc.so.6 => /nix/store/7jzp4zjxf499hqhm5gp1ijkraz24pln3-oracle-database-23c/opt/oracle/product/23c/dbhomeFree/lib/stubs/libc.so.6 (0x00007f10d6e00000)
        /nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/ld-linux-x86-64.so.2 => /nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib64/ld-linux-x86-64.so.2 (0x00007f10de4f5000)

Can you give me some directions?

I’ve published a flake containing the derivation, feel free to contribute to it at GitHub - drupol/nix-oracle-db

Once I’ll get something working, I’ll commit it to nixpkgs.

1 Like

I don’t have much time to try, but first, I’m surprised, don’t you need autoPatchelfHook to patch the link to the loaders? (autoPatchelfHook might only patch stuff in the bin folder, so you might need to copy the binaries in $out/bin and libraries in $out/lib) Otherwise, I would use strace ./yourprogram to debug this, looking for the list of path it tries to open. It might try to dlopen a library that is not present…

You should try the latest version of the repo, I just succeeded to run sqplus using buildFHSEnv. Apparently, @K900 told me on Matrix that patching the ELF file might not be a good idea, since he believes that Oracle has integrity checks (looks like he was right, once again!).

Now, what’s left to do in here, is to be able to run binaries transparently within a simple derivation.

I tried to do this: https://github.com/drupol/nix-oracle-db/blob/e69b4804ca9edd4181917f49ff5223b0b09aaeec/packages/oracledb.nix#L78 but it doesn’t work.
I need to find a way to bind all the binaries from the buildFHSEnv into the derivation… Help is very welcome on this!

Yeah, I usually try to avoid buildFHSEnv when possible, but in case of integrity checks it is hard to avoid.

That’s a good question… I’m not sure if there is a direct way to specify multiple runScript in a buildFHSEnv (maybe create an issue for that?). One solution might be to create a first derivation with buildFHSEnv that does not sets runScript (this way it is just bash), and then create another derivation that wraps it by calling the appropriate binary, like ${yourFHS}/bin/foo -c "myprogram" will call bash -c "myprogram", so you might be able to write something like:

let myDerivation = buildFHSEnv {name = "foo"; …}; in
runCommand "myProgram" {} ''
  mkdir -p $out/bin
  cd ${myDerivation}/opt/oracle/product/23c/dbhomeFree/bin
  for $file in $(ls) do
    # Goal: since by default runScript is bash, we try to run bash
    makeWrapper $out/bin/$file ${myDerivation}/bin/foo --add-flags "-c" --add-flags '"$file"' 
  done
'';

but this certainly need some more work as I can’t test it right now. Also, this will not propagate the arguments correctly as they need to be inside the argument to -c and not sure how to do that with makeWrapper directly…

You can also run one buildFHSEnv per binary, which is what they do here https://github.com/NixOS/nixpkgs/blob/a95d98f05a5da6cf66bef2584cf7a70b474d4518/pkgs/applications/misc/bottles/fhsenv.nix , this is certainly the simplest approach, but not sure how clean it is.

But someone certainly knows a better solution here.

Yep, I’m totally blocked right now, I can’t link the binaries provided by Oracle through the FHSEnv.

I simply cannot find a way to build a derivation where each executable in $out/bin is a script that sets up an FHS env and execs the analogous original binary from the Oracle release.

I’ve found a solution, but it’s very ugly. I hope there are alternatives.

I have improved the package, I’m looking for reviewers.

I will slowly start to work on the NixOS module if I find the energy in the upcoming days.

User contributions are very welcome!