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

automation and filedescriptorset usage #1

Closed
wants to merge 16 commits into from
Closed

Conversation

clux
Copy link
Member

@clux clux commented Aug 22, 2021

minor tweaks, i'm still struggling to get the servicegenerator to do something, but saw this pattern around and thought, this is probably a good way to sanity assert. had misunderstood servicegenerator (same as you, and had failed to remember). will explore the FDS path.

  • moves generated protos list output to protos.list (with include_str! -> split)
  • moves the fds output to protos.fds
  • using both files as inputs in build.rs to avoid copying anything
  • adds a POC file appending mechanics at the end of build.rs (committed a comment line for each api)

also moves generated protos list into an input file that i've called
protos.list for now.

Signed-off-by: clux <[email protected]>
@clux clux changed the title add a service generator for build.rs sanity service generator plus script runner Aug 22, 2021
trying just here as well because we are already doing cool stuff with sd
and gron.

Signed-off-by: clux <[email protected]>
@clux
Copy link
Member Author

clux commented Aug 22, 2021

goofed around a bit with just in here as well to try to order all the scripts in here accordingly:
Screenshot from 2021-08-22 16-27-30

@clux clux changed the title service generator plus script runner automation and filedescriptorset usage Aug 22, 2021
@clux
Copy link
Member Author

clux commented Aug 22, 2021

Edited a lot and updated. Went with your FileDescriptorSet route, which seems viable. I think we can continue on from something like this and find corresponding types from the api-resources.json and inject as appropriate.

I'm going to be away for a few days. If you want this feel free to squash (to get rid of my failed ServiceGenerator experiments), or fixup. Otherwise I can continue on later in the week (but probably not super actively).

build.rs Outdated
prost_build::Config::new()
// should probably switch to this
//.btree_map(&["."])
.out_dir("./out")
Copy link
Member

Choose a reason for hiding this comment

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

It's fine for now, but we shouldn't output outside OUT_DIR set by cargo in build scripts (out/ was copied from there for reference).

Build scripts may save any output files in the directory specified in the OUT_DIR environment variable. Scripts should not modify any files outside of that directory.
https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script

Copy link
Member Author

Choose a reason for hiding this comment

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

How should we copy this effectively if we don't hardcode the output path? The cargo build --out-dir flag is unstable (and by the looks of things is unlikely to get stabilised soon), so don't see how we can effectively piggy-back on top of OUT_DIR.

With OUT_DIR, the output happens to be within target/debug/build/k8s-pb-790fe4bcffd42aa5/out/api.core.v1.rs in my case, but it's a bit awkward to grab from. Should we write the "final output" at the end of the build.rs script instead?

Copy link
Member

Choose a reason for hiding this comment

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

I think we should have k8s-pb-codegen binary crate, like k8s-openapi-codegen. This is why I thought codegenrs (#3) might be useful. It seems to make it easy to set this up. I haven't looked into it, though.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, yeah, we definitely need another place to keep most of the logic at the very least. Tried a little bit to build on top of build.rs and the debug flow there is hard. I'll try to look more at it tomorrow 💤

build.rs Outdated
use std::io::Write;
if let Some(pkg) = f.package {
let pkgpath = std::path::Path::new("./out").join(format!("{}.rs", pkg));
let generics = format!("// TODO genericsfor {}\n", pkg);
Copy link
Member

Choose a reason for hiding this comment

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

I think we can continue on from something like this and find corresponding types from the api-resources.json and inject as appropriate.

Yeah, we should be able to get all structs within this package from f.message_type vec.

Copy link
Member Author

Choose a reason for hiding this comment

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

Have some time to start looking at this properly again now. Matching seems possible, but I might need to restructure the root keys in api-resources.json. The apiGroupVersion seems a little hard to match with f.package (and AFAIKT i don't have a better one in the FileDescriptorSet from a quick debug dump).

justfile Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
Remove `gron` dependency and make it easier to maintain patches.
this is just a sketch. i think we definitely need to move this
generation code elsewhere. the flow right now is very hard to deal with
(script breaks => no output, so have to output into the output files
instead).

Signed-off-by: clux <[email protected]>
@kazk
Copy link
Member

kazk commented Oct 14, 2021

https://github.com/influxdata/pbjson (pbjson-build) generates serde::Serialize/serde::Deserialize implementations from FileDescriptorSet. Maybe we can learn something from them.

@clux clux self-assigned this Oct 26, 2021
@kazk
Copy link
Member

kazk commented Oct 27, 2021

I got spec, status, and condition types for #4 easily, so I'm pushing it here. Hope you didn't have any local changes.

@kazk kazk force-pushed the protos-work branch 3 times, most recently from f6695a9 to c4cd3f5 Compare October 27, 2021 06:26
Signed-off-by: kazk <[email protected]>
Signed-off-by: kazk <[email protected]>
Basically a copy of `list-resources.jq` without `verbs` as a map.
Should be easier to use for codegen.

Signed-off-by: kazk <[email protected]>
@kazk
Copy link
Member

kazk commented Oct 27, 2021

Can we open a new PR without FileDescriptorSet for now?

With the new transform.jq, Pod looks like this:

{
  "api.core.v1.Pod": {
    "name": "pods",
    "namespaced": true,
    "apiGroupVersion": "v1",
    "group": "",
    "version": "v1",
    "kind": "Pod",
    "proto": "api.core.v1.Pod",
    "rust": "api::core::v1::Pod",
    "metadata": "apimachinery::pkg::apis::meta::v1::ObjectMeta",
    "spec": "api::core::v1::PodSpec",
    "status": "api::core::v1::PodStatus",
    "condition": "api::core::v1::PodCondition",
    "scopedVerbs": {
      "all": [
        "list"
      ],
      "namespaced": [
        "create",
        "delete",
        "deletecollection",
        "get",
        "list",
        "patch",
        "update"
      ]
    },
    "paths": [
      "/api/v1/pods",
      "/api/v1/namespaces/{namespace}/pods",
      "/api/v1/namespaces/{namespace}/pods/{name}"
    ],
    "subresources": [
      {
        "name": "attach",
        "scopedVerbs": {
          "namespaced": [
            "connect"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/attach"
        ]
      },
      {
        "name": "binding",
        "scopedVerbs": {
          "namespaced": [
            "create"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/binding"
        ]
      },
      {
        "name": "ephemeralcontainers",
        "scopedVerbs": {
          "namespaced": [
            "get",
            "patch",
            "update"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/ephemeralcontainers"
        ]
      },
      {
        "name": "eviction",
        "scopedVerbs": {
          "namespaced": [
            "create"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/eviction"
        ]
      },
      {
        "name": "exec",
        "scopedVerbs": {
          "namespaced": [
            "connect"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/exec"
        ]
      },
      {
        "name": "log",
        "scopedVerbs": {
          "namespaced": [
            "get"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/log"
        ]
      },
      {
        "name": "portforward",
        "scopedVerbs": {
          "namespaced": [
            "connect"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/portforward"
        ]
      },
      {
        "name": "proxy",
        "scopedVerbs": {
          "namespaced": [
            "connect"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/proxy",
          "/api/v1/namespaces/{namespace}/pods/{name}/proxy/{path}"
        ]
      },
      {
        "name": "status",
        "scopedVerbs": {
          "namespaced": [
            "get",
            "patch",
            "update"
          ]
        },
        "paths": [
          "/api/v1/namespaces/{namespace}/pods/{name}/status"
        ]
      }
    ]
  }
}
  • GVK, apiVersion
  • Name
  • metadata type for Metadata trait
  • spec type for HasSpec trait
  • status type for HasStatus trait
  • condition type for HasConditions trait
  • namespaced is true if resource can be namespaced. It can still have all verbs like list.
  • Scoped resource verbs
  • Scoped subresource Verbs

@clux
Copy link
Member Author

clux commented Oct 27, 2021

That's definitely a much better json to work with. and have also been sitting on this PR for too long :(

The FileDescriptorSet is only there so we can use the generated json to create impls, and atm it doesn't really do a whole lot; traverses the json path (which is probably wrong now), and appends a bit to the files. Are you suggesting we just comment out all of the FDS stuff from 39 -> 83 for now? Because that makes sense to me.

@clux
Copy link
Member Author

clux commented Oct 27, 2021

Guess there's also the rust structs i wrote for it in lib.rs, but we can drop all of that.

@kazk
Copy link
Member

kazk commented Oct 27, 2021

traverses the json path (which is probably wrong now), and appends a bit to the files.

I added a separate JSON transformed.json, so it should still work. We can remove the old one in the new PR.

Are you suggesting we just comment out all of the FDS stuff from 39 -> 83 for now? Because that makes sense to me.

I think we should create a new PR with automation and restructuring of the project (a separate codegen crate) that can be merged. Using FDS with transformed JSON is necessary, but it needs much more work, and it's difficult to iterate/collaborate without having the new structure merged first.

@kazk
Copy link
Member

kazk commented Oct 27, 2021

Or, we can just comment out the code and merge this after cleaning up some commits and fixing DCO.

@clux
Copy link
Member Author

clux commented Oct 27, 2021

I can remove the FDS stuff from this PR quickly if that's ok, then maybe just merge this and I'll open a new PR later with my stashed FDS stuff.

@clux
Copy link
Member Author

clux commented Oct 27, 2021

This commit builds and removes my changes to the generated files (it just maintains the automation): 64ebaa4 if it's ok you can git cherry-pick it in (wasn't able to create a pr into this branch).

@kazk
Copy link
Member

kazk commented Oct 27, 2021

(wasn't able to create a pr into this branch)

Yeah, that's because this branch is in your fork.

I'll open a new PR later with my stashed FDS stuff.

Sorry if the changes I pushed I messed it up. This is also why I'd like to merge this, so we can open PRs branching from here. I'll cherry pick. Is it ok if I just drop the commits for ServiceGenerator attempts (squash them)?

@clux
Copy link
Member Author

clux commented Oct 27, 2021

Nah, it's fine. I didn't want to impose by pushing straight into this.

But, yeah sounds great. Cherry pick, and rebase drop / squash away what you don't like! Will be great to have this stuff in main!

@kazk
Copy link
Member

kazk commented Oct 27, 2021

Superseded by #5. Pushed to a new branch just in case I messed up something while rebasing.

@kazk kazk closed this Oct 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants