-
Notifications
You must be signed in to change notification settings - Fork 195
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
Allow Update Driver Registration #2459
Allow Update Driver Registration #2459
Conversation
The first commit looks good - mind splitting that off to a separate PR we can merge now? And it should be straightforward to extend the change to |
7bf4c69
to
3629809
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good, and I think you've done an awesome job digging into a lot of the code here! I just have almost entirely optional stuff, basically seems OK to land to me; let's just do the const char*
etc. type tweaks.
I would say though I'd like to do the DBus property path over having the client parse the file, but we can indeed do that later.
3629809
to
8dad830
Compare
@cgwalters Thanks for the review! I've made all the suggested changes except #2459 (comment). It seems to me that a key-value dictionary would be easier to use than a tuple if there were many fields in the driver info. Though my assumption that we may want additional information about the update driver could be wrong, so I'm happy to simplify it to a 2-tuple since we only have two pieces of information for now if you think that's cleaner :) |
@@ -1081,6 +1093,13 @@ rpmostree_builtin_status (int argc, | |||
else | |||
cached_update_node = json_node_new (JSON_NODE_NULL); | |||
json_builder_add_value (builder, cached_update_node); | |||
json_builder_set_member_name (builder, "update-driver"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, seems like the JSON is missing the update driver ID, no?
But actually, it's even easier than that: you can just pass the deserialized GVariant
object directly like we do for transaction
above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I left that out because the update driver ID could potentially be empty if the transaction wasn't called with e.g. RPMOSTREE_CLIENT_ID=testing-agent-id
. But on second thought, I think if we're calling the --register-driver
option, we should make sure the caller supplies the update driver ID, and return an error if not, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah probably. However...we should debate a little whether the "id" should be the central thing or whether the systemd unit should be.
Probably the axis here is around the MCO versus not - when talking to rpm-ostree from a Kubernetes pod you just get a not-human-readable auto-generated cgroup slice. But when doing it from a host systemd service you get a nice e.g. zincati.service
. (It's a little less nice in the case of gnome-software but it's still not bad, at least it includes the software name) e.g.:
[root@quicksilver ~]# journalctl -u rpm-ostreed|grep client.*software | head -1
Jan 11 13:53:41 quicksilver rpm-ostree[2691]: client(id:gnome-software dbus:1.110 unit:app-gnome-gnome\x2dsoftware\x2dservice-2334.scope uid:1000) added; new total=1
[root@quicksilver ~]#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an interesting parallel to this debate which is: identifying software from the dpkg/RPM package name versus the systemd unit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the middle ground is: if the systemd unit ends in .service
, use it. Otherwise, use the client ID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I definitely think we should teach the MCO to use this.
Agree that we should enforce id
being provided with --register-driver
and display it prominently. The systemd unit can stay just in the journal logs for now. (Or perhaps conditionally display it with the -v
i.e. opt_verbose
option)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing worth noting is that RPMOSTREE_CLIENT_ID
today only has an effect if the driver is using the CLI, and only if the CLI decides to register via RegisterClient
. AFAICT, this is currently not the case for Zincati because it runs as a separate UID which systemd doesn't consider active
. E.g. from my FCOS server:
Jan 19 12:09:09 obelix rpm-ostree[2605951]: Initiated txn Deploy for client(dbus:1.5847 unit:zincati.service uid:980): /org/projectatomic/rpmostree1/fedora_coreos
(Notice how it doesn't have an id:...
.)
So we'll have to tweak this. Also worth noting that the env var is just an override to the default cli
, which isn't very useful (but would still pass through the --register-driver
check of requiring an ID). And at the D-Bus level, providing a client ID means the client has to call RegisterClient
, which so far hasn't been necessary (though it's clearly not a big deal to require it).
Hmm... I wonder if we should just leave the client ID as a thing we log to help debugging but otherwise not really promote it to the status
and instead have register-driver
take a human-readable string like "Zincati", or "Machine Config Operator". Something meaningful that users can just copy/paste into their search engine (which IMO is one of the primary goals of #1747). Then it's also obvious that it's required and it makes the API cleaner, because the option itself takes a value. (And maybe then we can have a special <systemd_unit_description>
value or something which just tells rpm-ostree to use the Description
of the associated systemd unit).
Anyway, don't mean to derail this, but worth discussing. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh I see. Yeah I haven't actually tested this with Zincati so I wasn't aware of that. In that case I agree we should make --register-driver
take in an argument - a human readable string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noting:
Also worth noting that the env var is just an override to the default
cli
I tried playing around in the CLI with my builds of rpm-ostree and it seems that if I don't provide the env var, the ID will indeed be NULL.
Edit: never mind, found the reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah wow, I guess coreos/zincati@c214f3e wasn't tested? I had thought that was working.
Mmmm...OK I guess we can just add a string to the driver.
8dad830
to
2fd0088
Compare
2fd0088
to
69a1bc8
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
All looking good now to me, just a few things that we can do as a followup commit!
src/app/rpmostree-builtin-deploy.cxx
Outdated
@@ -49,6 +50,7 @@ static GOptionEntry option_entries[] = { | |||
{ "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL }, | |||
{ "disallow-downgrade", 0, 0, G_OPTION_ARG_NONE, &opt_disallow_downgrade, "Forbid deployment of chronologically older trees", NULL }, | |||
{ "unchanged-exit-77", 0, 0, G_OPTION_ARG_NONE, &opt_unchanged_exit_77, "If no new deployment made, exit 77", NULL }, | |||
{ "register-driver", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_register_driver, "Register the calling agent as the driver for updates. Takes a human-readable string as name for driver", "DRIVERNAME" }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Should this really be G_OPTION_FLAG_HIDDEN
? I don't see a problem making this officially stable.
{ | ||
g_set_error (error, RPM_OSTREED_ERROR, | ||
RPM_OSTREED_ERROR_FAILED, "update driver name not provided"); | ||
return FALSE; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ | |
g_set_error (error, RPM_OSTREED_ERROR, | |
RPM_OSTREED_ERROR_FAILED, "update driver name not provided"); | |
return FALSE; | |
} | |
return glnx_throw (error, "update driver name not provided"); |
return FALSE; | ||
|
||
*driver_g_variant = | ||
g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE_VARDICT, data, FALSE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be a bit more idiomatic to have the return value here be GVariant*
and NULL
on error.
Hmm this looks like a real bug:
To debug this try doing e.g.:
And inside the VM use e.g. |
e0b61f6
to
bf20179
Compare
@cgwalters sorry for dragging this one out for so long. I've addressed the feedback from your latest review and CI is passing now. |
bf20179
to
a5e92b4
Compare
Nice! |
/lgtm cancel |
We had a realtime discussion about this, turns out I think I suggested the wrong thing in review; since the driver info is optional we need to make it be:
which is basically simulating In C++/Python/Java that use use implicit exceptions over reifed errors, the "happy path" looks nice since it's just Go has reified errors but there you just kind of get tired of typing I think Rust really did this correctly by reifying errors but making them easy to handle with |
Record the calling agent's systemd unit and serialize it into a g-variant file at `/run/rpmostree/update-driver.gv`, along with the human-readable name of the update driver provided as a string argument. Also add the companion `--register-driver` option to the `deploy` CLI argument. Closes coreos#1747.
Read from `/run/rpm-ostree/update-driver.gv` and display the update driver name (and systemd unit if verbose).
a5e92b4
to
e6bf1d3
Compare
/lgtm edit: looks like I can’t lgtm my own PR (which makes total sense). @cgwalters might need to bother you again 😄 |
@kelvinfan001: you cannot LGTM your own PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: kelvinfan001 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Record agent's systemd unit in each transaction and add D-Bus API option (for use by update drivers, e.g. Zincati) for serializing agent information into a JSON file in
/run
. Teachrpm-ostree status
to read from this JSON file and at least be able to display its update driver's systemd unit for now.Closes #1747.