Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create bindles from Spin apps #90

Merged
merged 1 commit into from
Feb 24, 2022
Merged

Conversation

itowlson
Copy link
Contributor

This is still WIP - it works, but it needs the new bindle loader that hasn't merged to main yet, and is unpleasantly coupled to the loader internals. We'll discuss how to mitigate that but in the meantime here it is for people to play with!

@itowlson
Copy link
Contributor Author

For those who want to have a go, the command is spin bindle push --app spin.toml (there is also a spin bindle prepare if you want to create a standalone bindle to gaze lovingly at). It uses your existing BINDLE_URL environment variable (or of course you can specify on the command line). There is no authentication. signing or 'skip TLS' at the moment.

@radu-matei
Copy link
Member

Looking at the generated parcel for spin.toml — is the name correct here?

[[parcel]]
[parcel.label]
sha256 = "b3bfcb3d92b9c2663a4f9c81e52720e6a68957ff40cd2fd55894fb2d67e3187b"
mediaType = "application/vnd.fermyon.spin+toml"
name = "/private/var/folders/rs/7g5937rn0sq1vyrtwf0_48140000gn/T/.tmpvaCd7h/manifests/spin.b3bfcb3d92b9c2663a4f9c81e52720e6a68957ff40cd2fd55894fb2d67e3187b.toml"
size = 181

@radu-matei
Copy link
Member

Bumping into the following serialization issue:

Error: Failed to expand 'spin.toml' to a bindle

Caused by:
    0: Failed to write app manifest to TOML
    1: values must be emitted before tables

Here is the full application manifest:

name = "fermyon.com"
apiVersion = "0.1.0"
version = "1.0.0"
description = "The Fermyon website running on Spin."
authors = [ "Fermyon Engineering <engineering@fermyon.com>" ]
trigger = {type = "http", base = "/" }


[[component]]
source = "spin-bartholomew.wasm"
id = "bartholomew"
files = [ "content/**/*" , "templates/*", "scripts/*", "config/*"]
[component.trigger]
route = "/..."

[[component]]
source = "ffs.wasm"
id = "fileserver"
files = ["static/**/*"]
environment = { PATH_PREFIX = "static/" }
[component.trigger]
route = "/static/..."

@itowlson
Copy link
Contributor Author

Effing values must be emitted before tables. Usually means something was empty when I expected it not to be. I'll take a look - thanks!

Re the invoice - the name of the manifest parcel isn't used, but yeah, it would be better to omit it than to leak the name of the temp file it got staged to. Thanks!

@itowlson
Copy link
Contributor Author

itowlson commented Feb 21, 2022

The Rust client requires us to provide a parcel name (even though the spec says it's optional). And the BindleWriter (which has been moderately battle tested as part of Hippo) currently relies on the name to locate the source file. So this might be a slightly fiddly fix.

@itowlson
Copy link
Contributor Author

The other one is because serde's TOML implementation requires the schema struct to put all collections after all scalars in the struct source code. In our case, we had environment before files, and files in the Bindle manifest is a scalar.

@radu-matei
Copy link
Member

Trying to push the template application after the latest changes (accommodating for the missing apiVersion field`):

➜ spin bindle push --app spin.toml
Error: Failed to push bindle to server

Caused by:
    Error pushing bindle to server: Error creating request

(this worked previously)

@radu-matei radu-matei mentioned this pull request Feb 22, 2022
1 task
@itowlson itowlson force-pushed the bindle-publish branch 2 times, most recently from 76cc930 to 2da0d0a Compare February 23, 2022 04:17
.with_context(|| format!("Failed to collect file mounts for {}", pattern))
});
let collections = results.into_iter().collect::<Result<Vec<_>>>()?;
let collection = collections.into_iter().flatten().collect();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to avoid the three iterations over the patterns here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. There probably is, but I haven't found it. The into_iter on 59 is redundant though, as result is already an iterator. We might need to create a custom flatten_or_fail combinator which I think I had in the Hippo CLI but essentially did the same thing!
  2. Could you elaborate on what you hope to achieve by doing so? If you're thinking about performance, the file accesses will absolutely dwarf the traversal. If it's clarity of expression then that's a good reason but let's just wrap the current code up in a combinator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was mainly clarity.
To be clear, this is by no means blocking.

impl BindleWriter {
pub async fn write(&self) -> anyhow::Result<()> {
// This is very similar to bindle::StandaloneWrite::write but... not quite the same
let bindle_id_hash = self.invoice.bindle.id.sha();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is this variable binding used anywhere else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's used on the next line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(other than the next line that was)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's the only place it's used... but that's enough isn't it? Not sure what you're getting at here, sorry.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I should have been more clear to begin with.
As a personal preference, whenever there are variables that are only used once, I rethink whether there actually needs to be a variable binding there at all. In this case:

let bindle_dir = self.dest_dir.join(invoice.bindle.id.sha());

This is very nitpicky, don't feel like you have to take this into account.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SO MANY PHILOSOPHICAL RIFTS


pub use bindle_pusher::push_all;
pub use bindle_writer::write;
pub use expander::expand_app_manifest;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given Bindle is the only implementation for this crate, would it make sense to drop the bindle_ prefix from the files? And if we do that, how about just push, write, expand instead of the nouns?
(this is just a personal preference.)

Copy link
Member

@radu-matei radu-matei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually tested with a rather complicated application, and everything seems to work great!

I left a bunch of comments, most of them rather nitpicky, and definitely nothing blocking.
This is awesome, thank you!

@itowlson itowlson marked this pull request as ready for review February 24, 2022 02:43
Copy link
Member

@radu-matei radu-matei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yaaay, this looks great, thank you SO much!

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants