dontlaugh/packer-provisioner-deno

Upload and execute bundles

Closed this issue · 2 comments

Bundling support is almost here. Test it out and upload bundles into virtual machines and containers for bigger, more complex provisioning use cases.

The idea here is to avoid fetching and compiling code on the target machine, so we will require (by default), a local deno installation. This will speed up repeated packer builds since unchanged bundles could be cached and uploaded right away (instead of fetching/recompiling every time on the clean target environment).

We should, of course, allow overriding this behavior so that deno on the target machine can fetch and compile code. Not everyone who runs packer will want or be able to install Deno locally. But I think the common case will benefit from local compilation.

Besides, I want to figure out the whole ship-compiled-code thing ;-)

The strategy I'm currently pursuing:

  • Locally the packer plugin takes a relative path blah/foo.ts
  • A tempfile path is generated, something like /tmp/packer-provisioner-deno/foo.ts.js
  • We bundle with an explicit outfile `deno bundle blah/foo.ts /tmp/packer-provisioner-deno/foo.ts.js
  • The bundled version is uploaded into the VM/container under /tmp
  • as root we execute the bundled version with fully-qualified path e.g. deno run -A /tmp/foo.ts.js

Deno seems to care about the file extension. This is important because we are generating our own outfile path. If we don't change it from ".ts", we get:

==> docker: Uploading deno scripts...
    docker: Creating directory: /tmp/packer-deno
    docker: Uploading /tmp/packer-provisioner-deno854161685/makeuser.ts
    docker: Uploading /tmp/packer-provisioner-deno252733296/install-nginx-ubuntu.ts
==> docker: Running provisioning scripts
==> docker: /root/.local/bin/deno -A /tmp/packer-deno/makeuser.ts
==> docker: Compile file:///tmp/packer-deno/makeuser.ts
==> docker: /root/.local/bin/deno -A /tmp/packer-deno/install-nginx-ubuntu.ts
==> docker: Compile file:///tmp/packer-deno/install-nginx-ubuntu.ts
==> docker: error: Uncaught ImportPrefixMissing: relative import path "require" not prefixed with / or ./ or ../ Imported from "file:///tmp/packer-deno/install-nginx-ubuntu.ts"
==> docker: ► $deno$/dispatch_json.ts:40:11
==> docker:     at DenoError ($deno$/errors.ts:20:5)
==> docker:     at unwrapResponse ($deno$/dispatch_json.ts:40:11)
==> docker:     at sendAsync ($deno$/dispatch_json.ts:91:10)
==> docker: Killing the container: c399b8de2995fde899e9644b126e5aeaa21626cedce9937a6dd92750c90a162b
Build 'docker' errored: error running deno: /root/.local/bin/deno -A /tmp/packer-deno/install-nginx-ubuntu.ts non-zero exit status: 1

Note the compile step that deno reports.

If we append .js to the filename we get

==> docker: Uploading deno scripts...
    docker: Creating directory: /tmp/packer-deno
    docker: Uploading /tmp/packer-provisioner-deno105784957/makeuser.ts.js
    docker: Uploading /tmp/packer-provisioner-deno779721144/install-nginx-ubuntu.ts.js
==> docker: Running provisioning scripts
==> docker: /root/.local/bin/deno run -A /tmp/packer-deno/makeuser.ts.js
==> docker: /root/.local/bin/deno run -A /tmp/packer-deno/install-nginx-ubuntu.ts.js
==> docker: error: Uncaught TypeError: define is not a function
==> docker: ► file:///tmp/packer-deno/install-nginx-ubuntu.ts.js:1:1
==> docker: 1 define("nginx", ["require", "exports"], function (require, exports) {
==> docker:   ^
==> docker:     at file:///tmp/packer-deno/install-nginx-ubuntu.ts.js:1:1
==> docker: Killing the container: 603befd238fa874df8f247f0595a4a2984e13a89f2ae0dbb9aed2e94aa778fe0
Build 'docker' errored: error running deno: /root/.local/bin/deno run -A /tmp/packer-deno/install-nginx-ubuntu.ts.js non-zero exit status: 1

The makeuser.ts.js script has no imports and executes fine.

So a problem here is that locally I was compiling with v0.20, which is quite out of date. And in the target container I was running the latest install. Bundling formats have changed a lot.

Locally on my laptop I was still using $HOME/.deno/bin which is no longer where the install/upgrade script puts things. Instead we need to use $HOME/.local/bin