#Issue with publishing multi-platform with NodeJS

1 messages · Page 1 of 1 (latest)

glossy arch
#

I get the following error: ```GraphQLRequestError: Error message
at file:///Users/alexbowers/Development/jobilla/omnia/build/dagger/node_modules/.pnpm/@dagger.io+dagger@0.4.1/node_modules/@dagger.io/dagger/dist/api/utils.js:121:23
at Generator.throw (<anonymous>)
at rejected (file:///Users/alexbowers/Development/jobilla/omnia/build/dagger/node_modules/.pnpm/@dagger.io+dagger@0.4.1/node_modules/@dagger.io/dagger/dist/api/utils.js:5:65)
at processTicksAndRejections (node:internal/process/task_queues:95:5) {
cause: ClientError: Syntax Error GraphQL request (2:138) Expected Name, found String "_queryTree"

1:
2: { container { publish (address: "registry.gitlab.com/jobilla/backend-services/migrations/migrated-8:latest",platformVariants: [{"_queryTree":[{operation:"container",args:{platform:"linux/amd64"}},{operation:"from",args:{address:"mysql:8.0"}},{operation:"withEnvVariable",args:{name:"MYSQL_USER",value:"jobilla"}},{operation:"withEnvVariable",args:{name:"MYSQL_PASSWORD",value:"jobilla"}},{operation:"withEnvVariable",args:{name:"MYSQL_DATABASE",value:"jobilla"}},{operation:"withEnvVariable",args:{name:"MYSQL_ROOT_PASSWORD",value:"password"}},{operation:"withExposedPort",args:{port:3306}},{operation:"withExec",args:{args:[]}}],clientHost:"127.0.0.1:56726",sessionToken:"f74916b3-f236-47e4-bd1f-58e367035a32",client:{url:"http://127.0.0.1:56726/query",options:{headers:{Authorization:"Basic Zjc0OTE2YjMtZjIzNi00N2U0LWJkMWYtNThlMzY3MDM1YTMyOg=="}}}},{"_queryTree":[{operation:"container",args:{platform:"linux/arm64"}},{operation:"from",args:{address:"mysql:8.0"}},{operation:"withEnvVariable",args:{name:"MYSQL_USER",value:"jobilla"}},..."}}}}]) } }

#

My code is as follows: ```async (client: Client, context: DaggerStepContext) => {
let migratedPlatformVariants = [];
let seededPlatformVariants = [];

    for (let platform of ['linux/amd64', 'linux/arm64']) {
        const db = client.container({platform} as ClientContainerOpts)
            .from("mysql:8.0")
            .withEnvVariable("MYSQL_USER", "jobilla")
            .withEnvVariable("MYSQL_PASSWORD", "jobilla")
            .withEnvVariable("MYSQL_DATABASE", "jobilla")
            .withEnvVariable("MYSQL_ROOT_PASSWORD", "password")
            .withExposedPort(3306)
            .withExec([]);

        let app = client.container()
            .from("jobilla/php:ci-8.0")
            .withServiceBinding("db", db)
            .withEnvVariable("APP_ENV", "testing")
            .withEnvVariable("DB_DATABASE", "jobilla")
            .withEnvVariable("DB_HOST", "db")
            .withEnvVariable("DB_PORT", "3306")
            .withEnvVariable("DB_USERNAME", "jobilla")
            .withEnvVariable("DB_PASSWORD", "jobilla")
            .withMountedDirectory("/app", client.host().directory(servicePath("application", "migrations")))
            .withWorkdir("/app")
            .withExec(["composer", "install"])
            .withExec(["php", "artisan", "migrate"]);

        await migratedPlatformVariants.push(db);

        app.withExec(["php", "artisan", "db:seed"]);

        await seededPlatformVariants.push(db);
    }

    await client.container().publish(`${registry}/${repository_group}/${repository}/migrated-8:latest`, {
        platformVariants: migratedPlatformVariants
    } as ContainerPublishOpts);

    await client.container().publish(`${registry}/${repository_group}/${repository}/seeded-8:latest`, {
        platformVariants: seededPlatformVariants
    } as ContainerPublishOpts);
}```
small lichen
#

Hey @glossy arch !
The content of the db variable is invalid GraphQL, that's why it's complaining.
This content should be wrapped in a Container query as follows:

Container {
  _queryTree: [
    { operation: 'container', args: [Object] },
    { operation: 'from', args: [Object] },
    { operation: 'withEnvVariable', args: [Object] },
    { operation: 'withEnvVariable', args: [Object] },
    { operation: 'withEnvVariable', args: [Object] },
    { operation: 'withEnvVariable', args: [Object] },
    { operation: 'withExposedPort', args: [Object] },
    { operation: 'withExec', args: [Object] }
  ],
  clientHost: '127.0.0.1:34489',
  sessionToken: '9e2f8a8e-f942-412f-a1e9-99cd7939c180',
  client: GraphQLClient {
    url: 'http://127.0.0.1:34489/query',
    options: { headers: [Object] }
  }
}
#

Can you add a console.log(db) before the app variable to see if the output is missing that wrapper (the query name)?

#

BTW, I assume you are also importing the connect method in your script and the snippet you sent is the callback function passed to the connect method.

small lichen
# small lichen Hey <@171010552020074497> ! The content of the `db` variable is invalid GraphQL,...

I get this output in the console after executing the following script:

import Client, { connect } from "@dagger.io/dagger";

connect(async (client: Client) => {
  let migratedPlatformVariants = [];
  let seededPlatformVariants = [];

  for (let platform of ["linux/amd64", "linux/arm64"]) {
    const db = client
      .container({ platform } as any)
      .from("mysql:8.0")
      .withEnvVariable("MYSQL_USER", "jobilla")
      .withEnvVariable("MYSQL_PASSWORD", "jobilla")
      .withEnvVariable("MYSQL_DATABASE", "jobilla")
      .withEnvVariable("MYSQL_ROOT_PASSWORD", "password")
      .withExposedPort(3306)
      .withExec([]);

    console.log(db);
  }
});
ionic nest
#

cc @junior spear @long frost seems to me this could be a bug in the TS SDK. Looks like when pushing with platformVariants, that generates an incorrect GraphQL query since it's not putting in place the correct container ID's

long frost
#

Yes, because the container has not been built for real with a exitCode, stdout or stderr.

#

Basically, @glossy arch , what you're trying to do is to create 2 versions of the DB: 1 that has been migrated, and the same one that has been seeded after being migrated, right?

#

And then, you want to publish those 2 images in the registry

#

If I'm thinking pure docker logic, those migrated schema and data would be put in a volume. I quite don't know where buildkit would put that ( @viscid flax if you can give us a hint here :))

#

But if that works, to really migrate those data, finishing a container by a : .withExec won't be enough, because this is lazy.
What you need is to run this via exitCode, stdout or stderr. Then it will actually do the work.
Also, you might have to publish the db container after each execution of migrate/seed, not just at the end.

glossy arch
#

How can I publish for both platforms that way if i publish it at the time it's made? Or is platformVariants jus an option but if i have 2 different platforms then its published to the same place anyway?

ionic nest
#

I'm trying this and it doesn't work for me :

import Client, { connect } from "@dagger.io/dagger";
import { ClientContainerOpts, ContainerPublishOpts } from "@dagger.io/dagger/dist/api/client.gen";

connect(async (client: Client) => {
    let migratedPlatformVariants = [];
    let seededPlatformVariants = [];

    for (let platform of ["linux/amd64", "linux/arm64"]) {
        const db = client
            .container({ platform } as ClientContainerOpts)
            .from("mysql:8.0")
            .withEnvVariable("MYSQL_USER", "jobilla")
            .withEnvVariable("MYSQL_PASSWORD", "jobilla")
            .withEnvVariable("MYSQL_DATABASE", "jobilla")
            .withEnvVariable("MYSQL_ROOT_PASSWORD", "password")
            .withExposedPort(3306)
            .withExec(["ls"]);

        await db.exitCode();

        seededPlatformVariants.push(db);

    }
    await client.container().publish(`docker.io/marcosnils/migrated-8:latest`, {
        platformVariants: seededPlatformVariants
    });

}, { LogOutput: process.stderr });
#

o

long frost
#

Let me check

ionic nest
#

invalid graphQL query

long frost
#

Yeah, it seems you're right.
@opal eagle it seems we have some problem where we get the queryTree when we're not supposed to get it already.

opal eagle
#

I'll have a look

junior spear
#

Ok I took a look on it and basically if we do the same query with the GoSDK, it will use the special XXX_GRAPHQL_ID to resolves the id and replace the container with it.
But in our case, we are keeping the queryTree and we are not resolving it correctly, maybe because it's an array

junior spear
#

@long frost @opal eagle Waiting for your review

ionic nest
#

@glossy arch this has been released yesterday. 🙌 . Let us know if you're still having any issues please 🙏

glossy arch
#

What version should I bump up to? latest?