prisma / prisma

Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB

Home Page:https://www.prisma.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ENV-based binary variables broken on preview022

radicand opened this issue · comments

I rebuilt the prisma engine binaries for ARM64 against the latest repo code, and am getting a strange issue when attempting to run a migration against a postgresql database: Error: Can't parse migration engine response: undefined. It works fine on the stock binaries provided for amd64, and if I purposely mess up the connection string I get a reasonable error back, but if the connection string is valid, then the above mentioned error occurs.

It's worth noting that if I export the debug flags and execute against the migration engine binary, I get:
./migration-engine cli --datasource postgresql://xxx:xxxx@postgres-postgresql:5432/xxxx --can_connect_to_database Feb 25 01:47:10.114 INFO quaint::single: Starting a postgresql pool with 1 connections. Feb 25 01:47:10.117 INFO quaint::connector::metrics: query="SELECT 1" item_type="query" params=[] duration_ms=2

however npx prisma2 migrate up --experimental still throws the above undefined error.

I've narrowed it down to something wrong with the *_BINARY env variables (and updated the topic accordingly). I did this by unsetting all my *_BINARY variables, and then manually copying the binaries to ./node_modules/prisma2/*-engine-debian-openssl-1.1.x . After this, everything ran as expected.

Ok, so you think the *_BINARY variables do not always work as expected, so using them to provide your own binaries is broken?

Can you maybe add which exact ENV var you were trying to use with which exact command? That would make it much easier to debug.

Also, you mention preview022 explicitly. Did this work with versions before?

(I also moved this issue to the prisma2 repo as it doesn't seem to be with the binaries of the Engines itself, but a problem how they are used. Please let me know if you disagree with this judgment)

Certainly:
Specifically - prisma2 migrate up --experimental . It may only be related to migration-engine, but I haven't had a chance to look at the others.

Just in case it helps, here's a quick and dirty reproduction anyone can do that shows it's ignoring the ENV for the migration engine binary. Ignore the P1001 error, that's expected if it's working. The end where it shows undefined is when the binary is not present, but it should also give this behavior once the ENV variable is set to a bad path as well, but doesn't.

❯ npx prisma2 migrate up --experimental
Error: P1001: Can't reach database server at `localhost`:`5432`

Please make sure your database server is running at `localhost`:`5432`.

❯ export PRISMA_MIGRATION_ENGINE_BINARY=node_modules/prisma2/migration-engine-darwin-bad

❯ npx prisma2 migrate up --experimental
Error: P1001: Can't reach database server at `localhost`:`5432`

Please make sure your database server is running at `localhost`:`5432`.

❯ rm node_modules/prisma2/migration-engine-darwin

❯ npx prisma2 migrate up --experimental
Error: Can't parse migration engine response:
undefined

Maybe also important, but if I do npm i after this charade, I get the below. The ENV variable set isn't actually undefined, but the error message seems to indicate it's being perceived that way.

❯ npm i

> graphql-auth@ postinstall /Users/npappas/Desktop/projects/cookbook/server
> npm -s run generate

Error: Env var PRISMA_MIGRATION_ENGINE_BINARY is provided but provided path undefined can't be resolved.

I can confirm this. Marking this as a regression.

commented

I got this issue with an incorrect connection string (unescaped password)
not saying the above issue is that but there are red herrings with this error message.

Thanks a lot for reporting 🙏
This issue is fixed in the latest alpha version of prisma2.
You can try it out with npm i -g prisma2@alpha.

In case it’s not fixed for you - please let us know and we’ll reopen this issue!

I updated to prisma2@alpha, unfortunately it doesn't appear to be resolved.

PRISMA_QUERY_ENGINE_BINARY seems to function as expected (to be honest I can't remember if there was an issue here or not), however PRISMA_MIGRATION_ENGINE_BINARY does not.
It resolves if I manually copy the binary to node_modules/prisma2/migration-engine-debian-openssl-1.1.x in my target environment.

Straightforward reproduction (assumes Mac environment, update binary paths as needed):

npx prisma2 migrate up --experimental # should work

mv $PWD/node_modules/prisma2/migration-engine-darwin $PWD/node_modules/prisma2/migration-engine-darwin2

export PRISMA_MIGRATION_ENGINE_BINARY=$PWD/node_modules/prisma2/migration-engine-darwin2

npx prisma2 migrate up --experimental #errors, but should succeed

I'm not familiar enough with the codebase, but is https://github.com/prisma/migrate/blob/046f665a7585ea6658a67f297d7ae3d877b316ea/src/liftEngineCommands.ts#L11 related at all? Somewhere binaryPath isn't being used it would appear.

I can confirm this on Windows with alpha 918:

C:\Users\Jan\Documents\throwaway\1722>set PRISMA_MIGRATION_ENGINE_BINARY=node_modules/prisma2/migration-engine-windows2.exe

C:\Users\Jan\Documents\throwaway\1722>npx prisma2 migrate up --experimental
[migration-engine] error: Error: spawn node_modules/prisma2/migration-engine-windows2.exe ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:264:19)
    at onErrorNT (internal/child_process.js:456:16)
    at processTicksAndRejections (internal/process/task_queues.js:77:11) {
  errno: 'ENOENT',
  code: 'ENOENT',
  syscall: 'spawn node_modules/prisma2/migration-engine-windows2.exe',
  path: 'node_modules/prisma2/migration-engine-windows2.exe',
  spawnargs: [Array]
}
Error: spawn node_modules/prisma2/migration-engine-windows2.exe ENOENT

prisma2 -v seems to look at the right location though:

C:\Users\Jan\Documents\throwaway\1722>npx prisma2 -v
Prisma CLI Version   : prisma2@2.0.0-alpha.918
Current platform     : windows
Query Engine         : prisma 4ff8379527ec7797e7bb5b55d374f82f5812a6f9 (at C:\Users\Jan\Documents\throwaway\1722\node_modules\prisma2\query-engine-windows.exe)
Migration Engine     : migration-engine-cli 4ff8379527ec7797e7bb5b55d374f82f5812a6f9 (at node_modules/prisma2/migration-engine-windows2.exe, resolved by PRISMA_MIGRATION_ENGINE_BINARY)
Introspection Engine : introspection-core 4ff8379527ec7797e7bb5b55d374f82f5812a6f9 (at C:\Users\Jan\Documents\throwaway\1722\node_modules\prisma2\introspection-engine-windows.exe)

After a first investigation it looks like only an absolute path works at the moment.
@radicand if it's still not working please post a full debug output from PRISMA_MIGRATION_ENGINE_BINARY=/Users/yourpath/migration-engine-darwin npx prisma2@alpha migrate up --experimental

The specification says that the path can be absolute or relative to the current working directory so I will fix that.

On alpha I still see it broken. I've been using absolute paths - the $PWD in my example above is resolved at the shell level before exporting in as an environmental variable.

Here's a debug dump exhibiting the same issue (latest alpha). I moved the migration engine binary to the project folder and ran the below commands. The first one appears to work, but when I delete the migration engine binary in node_modules (my production environment is ARM and I have to compile my own binaries, so this mimics reality), it chokes:

~/Desktop/projects/cookbook/backend auth0*
❯ PRISMA_MIGRATION_ENGINE_BINARY=/Users/me/Desktop/projects/cookbook/backend/migration-engine-darwin DEBUG=* npx prisma2 migrate up --experimental
  prisma .env not loaded +0ms
  engineCommands getConfig, override prismaPath = undefined +0ms
  getos { platform: 'darwin', libssl: undefined } +0ms
  getos { platform: 'darwin', libssl: undefined } +37ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +5ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +2ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +1ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +1ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +1ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  snapdragon:compiler initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +1ms
  snapdragon:parser initializing /Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js +0ms
  LiftEngine:rpc starting migration engine with binary: /Users/me/Desktop/projects/cookbook/backend/migration-engine-darwin +0ms
  LiftEngine:rpc SENDING RPC CALL {"id":1,"jsonrpc":"2.0","method":"listMigrations","params":{"projectInfo":"","sourceConfig":"generator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"postgresql\"\n  url      = env(\"DATABASE_URL\")\n}\n\nenum Permission {\n  AUTHOR ADMIN\n}\n\nmodel User {\n  id          String     @default(cuid()) @id\n  email       String     @unique\n  name        String\n  permissions Permission @default(AUTHOR)\n  recipes     Recipe[]\n}\n\nenum UnitType {\n  METRIC IMPERIAL\n}\n\nmodel UnitSize {\n  id       String   @default(cuid()) @id\n  name     String   @unique\n  plural   String\n  unitType UnitType @default(METRIC)\n}\n\nmodel Ingredient {\n  id   String @default(cuid()) @id\n  name String @unique\n}\n\nmodel IngredientUnit {\n  id         String     @default(cuid()) @id\n  ingredient Ingredient\n  unit       UnitSize?\n  amount     Float?\n  notes      String?\n}\n\nmodel Step {\n  id          String @default(cuid()) @id\n  description String\n}\n\nmodel RecipeSection {\n  id              String           @default(cuid()) @id\n  name            String\n  description     String?\n  prepTimeMinutes Int\n  cookTimeMinutes Int\n  servings        Int\n  servingUnit     String\n  ingredients     IngredientUnit[]\n  steps           Step[]\n}\n\nmodel Recipe {\n  id          String          @default(cuid()) @id\n  source      String?\n  author      User\n  title       String\n  description String?\n  notes       String?\n  tags        Tag[]\n  sections    RecipeSection[]\n  photo       String?\n  createdAt   DateTime        @default(now())\n  updatedAt   DateTime        @updatedAt\n}\n\nmodel Tag {\n  id      String   @default(cuid()) @id\n  name    String   @unique\n  recipes Recipe[]\n}\n"}} +5ms
  LiftEngine:stderr Mar 23 18:36:44.821  INFO migration_engine: Starting migration engine RPC server git_hash="377df4fe30aa992f13f1ba152cf83d5770bdbc85" +0ms
  LiftEngine:stderr Mar 23 18:36:44.848  INFO quaint::single: Starting a postgresql pool with 1 connections. +27ms
  LiftEngine:stderr Mar 23 18:36:44.862  INFO tokio_postgres::connection: NOTICE: schema "public" already exists, skipping     +13ms
  LiftEngine:stderr Mar 23 18:36:44.894  INFO ListMigrations: migration_core::commands::list_migrations: Returning 1 migrations (0 pending). +33ms
🏋️‍  migrate up

All migrations are already applied

~/Desktop/projects/cookbook/backend auth0*
❯ rm node_modules/prisma2/migration-engine-darwin

~/Desktop/projects/cookbook/backend auth0*
❯ PRISMA_MIGRATION_ENGINE_BINARY=/Users/me/Desktop/projects/cookbook/backend/migration-engine-darwin DEBUG=* npx prisma2 migrate up --experimental
  prisma .env not loaded +0ms
  engineCommands getConfig, override prismaPath = undefined +0ms
  getos { platform: 'darwin', libssl: undefined } +0ms
  getos { platform: 'darwin', libssl: undefined } +47ms
Error: Error: Can't parse migration engine response:
undefined
    at Object.canConnectToDatabase (/Users/me/Desktop/projects/cookbook/backend/node_modules/prisma2/build/index.js:2:118997)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

I did some additional testing/hacking, and can confirm two things:

  1. The issue appears restricted to Migrate only
  2. The core issue is most likely https://github.com/prisma/migrate/blob/master/src/liftEngineCommands.ts#L11 - it does not use PRISMA_MIGRATION_ENGINE_BINARY at all. I hacked in an if (process.env.PRISMA_MIGRATION_ENGINE_BINARY) { return process.env.PRISMA_MIGRATION_ENGINE_BINARY; } and migrate was working the way it should afterward.

Thanks a lot @radicand for pushing this forward!
I could not reproduce this in the past, but now it also explains to me why, because I had the real binaries always there.
I just pushed the fix you suggested, can you try it out with @prisma/cli@alpha?
Thanks!

Thanks @timsuchanek , I can confirm alpha has finally fixed the issue for me. I was able to launch my image using my alpine binaries and migrate ran properly as does the query engine. I think we're good to close this out!

@timsuchanek @radicand Even I had the same issue (screenshot below). Using @prisma/cli@alpha fixed it for me as well. And it happens when I used it within alpine. Not otherwise.

Screenshot from 2020-04-04 16-50-44

Will this fix be rolled out in the next beta? Thanks.

Yes, all alpha changes will bet in beta.2 of course.