nanos icon indicating copy to clipboard operation
nanos copied to clipboard

run go app with oracle client dependency

Open andreaneri opened this issue 4 years ago • 8 comments

Hello, I' am trying to run a golang application who has dependency by oracle client, how should I proceed in order to run it as unikernel ?

uname -a Darwin MacBook-Pro-3.homenet.telecomitalia.it 21.2.0 Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:54 PST 2021; root:xnu-8019.61.5~1/RELEASE_X86_64 x86_64

this is the output I get: ops run app_linux 100% |████████████████████████████████████████| [0s:0s] panic: failed building manifest: file does not exist

goroutine 1 [running]: github.com/nanovms/ops/cmd.runCommandHandler(0xc00048c580, 0xc000aa2300, 0x1, 0x1) /Users/eyberg/go/src/github.com/nanovms/ops/cmd/cmd_run.go:62 +0x45c github.com/spf13/cobra.(*Command).execute(0xc00048c580, 0xc000aa22e0, 0x1, 0x1, 0xc00048c580, 0xc000aa22e0) /Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:846 +0x2c2 github.com/spf13/cobra.(*Command).ExecuteC(0xc0000f5080, 0x0, 0xffffffff, 0xc0000b0058) /Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:950 +0x375 github.com/spf13/cobra.(*Command).Execute(...) /Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:887 main.main() /Users/eyberg/go/src/github.com/nanovms/ops/ops.go:8 +0x2a

thanks,

Andrea

andreaneri avatar Jan 30 '22 10:01 andreaneri

probably going to need a bit more information than that

  1. is the oracle client a go dependency? (such as in go.mod?) or is it something else?

  2. looks like you might be missing a file ?

eyberg avatar Jan 30 '22 17:01 eyberg

  1. this is the import in my source: _ "github.com/godror/godror"

  2. I created volume in this way: ops volume create oracle -d /opt/oracle/instantclient_21_5 2022/01/30 20:01:31 volume: oracle created with UUID 16419057-5861-fa3e-98b5-f10cf31c41c2 and label oracle

that contain the oracle client for linux, as i do with container,

I tried to run: ops run app_linux --mounts 16419057-5861-fa3e-98b5-f10cf31c41c2:/opt/oracle/instantclient_21_5

but the message is yet: panic: failed building manifest: file does not exist

goroutine 1 [running]: github.com/nanovms/ops/cmd.runCommandHandler(0xc00068e840, 0xc0007b4600, 0x1, 0x3) /Users/eyberg/go/src/github.com/nanovms/ops/cmd/cmd_run.go:62 +0x45c github.com/spf13/cobra.(*Command).execute(0xc00068e840, 0xc0007b45d0, 0x3, 0x3, 0xc00068e840, 0xc0007b45d0) /Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:846 +0x2c2 github.com/spf13/cobra.(*Command).ExecuteC(0xc0004b1080, 0x0, 0xffffffff, 0xc00004e0b8) /Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:950 +0x375 github.com/spf13/cobra.(*Command).Execute(...) /Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:887 main.main() /Users/eyberg/go/src/github.com/nanovms/ops/ops.go:8 +0x2a

how should i set LD_LIBRARY_PATH as i do in my dockerfile ? thanks

Andrea

andreaneri avatar Jan 30 '22 19:01 andreaneri

is there a reason why you are attaching a volume to the app vs including that directory inside your image via 'Dirs' or 'MapDirs' ?

also, it looks like you are hitting the same problem with or without the volume; do you have a minimal example to look at?

i haven't downloaded oracledb yet but something like this should work:

eyberg@box:~/o$ cat config.json
{
  "Dirs": ["instantclient_21_5"]
}
eyberg@box:~/o$ cat main.go
package main

import (
  "fmt"
  "database/sql"
  _ "github.com/godror/godror"
)

func main() {
  db, err := sql.Open("godror", `user="scott" password="tiger" connectString="dbhost:1521/orclpdb1"
                               libDir="instantclient_21_5"`)
  if err !=nil {
    fmt.Println(err)
  }

   defer db.Close()
   db.Ping()
}

eyberg@box:~/o$ ops run -c config.json o

two things to watch out for:

  1. you are on a mac so you'll want to cross-compile to linux && use the linux instantclient libraries

  2. I don't think you need to set LD_LIBRARY_PATH (we don't have that anyways) but you can instead set the directory of where those libraries are so it can be loaded

eyberg avatar Jan 30 '22 19:01 eyberg

to give you a parallel with what I do with container, I attach a volume to keep image slim (oracle client weight is around 256Mb), 1- of course, i compile for linux in a linux container (I tried with zig but I failed), and after i copy elf from running container: file app_linux app_linux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, Go BuildID=57R30IaEqwva7GwJHJ0g/8y-XXVGSAree9TQcAEJv/Z_oSeHg0Dp4dFwMUOP3L/A3VT7FNpYNOMUIFRJD64, BuildID[sha1]=c455a0d25f428afc7cc7f97c3f264efb3ea20a1c, not stripped

I use oracle client for linux,

2- to be honest I didn't use the parameter libDir of the driver till now, but following your example the output is the same: panic: failed building manifest: file does not exist

is there a way to have a more detailed debug output ? thanks,

Andrea

andreaneri avatar Jan 30 '22 20:01 andreaneri

that panic is definitely something that should be more explicit (like what file it is failing to find) for sure but more than likely it's trying to add a file that it can't find on your mac - it might help to sprinkle some printfs into the BuildManifest function where it is failing

https://github.com/nanovms/ops/blob/882d741c6db5ea41e99d1801adc31dea7790153f/lepton/image.go#L304

if you do a ldd app_linux on linux can you paste that output? my wag is that you have a lib there that needs to be copied as well - on that note do you have trouble building/running under linux vs mac? - were you able to build the example I pasted?

eyberg avatar Jan 30 '22 21:01 eyberg

root@3621002adc2a:/go/src/cmd/web# ldd cmd/web/app linux-vdso.so.1 (0x00007ffe33dde000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb43c276000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb43c255000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb43c094000) /lib64/ld-linux-x86-64.so.2 (0x00007fb43c281000) I expected that libc is what ops command build around elf application file, hope this is useful,

were you able to build the example I pasted? yes of course, i changed my source to use libDir parameter of godror, after that: I built again for linux I created config.json I put at the root level (where i run ops run) directory instantclient_21_5

andreaneri avatar Jan 30 '22 21:01 andreaneri

ops is libc agnostic and if you build/run on linux it will try to resolve all those shared libraries (eg: auto-include them) but if you are just yanking down a binary without the libs it depends on to mac then you have a high chance of running into an issue like this - I'm going to guess that libdl dep you have is what is causing the issue and that is there because of the cgo build from the oracle lib that loads at run-time

so just to be clear you can build/run this on linux just not mac?

eyberg avatar Jan 30 '22 22:01 eyberg

yeah, I will and ill let you know

andreaneri avatar Jan 30 '22 22:01 andreaneri