-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Let fluxd answer queries without a git repo supplied #962
Conversation
109f8fa
to
5728904
Compare
5728904
to
77467b2
Compare
77467b2
to
1b4dfff
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.
Few nitpicks, bit of code praise, some questions.
cmd/fluxd/main.go
Outdated
"email", *gitEmail, | ||
"sync-tag", *gitSyncTag, | ||
"notes-ref", *gitNotesRef, | ||
"set-author", *gitSetAuthor) |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
EventWriter: eventWriter, | ||
Logger: log.With(logger, "component", "daemon"), LoopVars: &daemon.LoopVars{ | ||
Logger: log.With(logger, "component", "daemon"), | ||
LoopVars: &daemon.LoopVars{ |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
cluster/cluster.go
Outdated
@@ -29,6 +29,10 @@ type Cluster interface { | |||
type Controller struct { | |||
ID flux.ResourceID | |||
Status string // A status summary for display | |||
// Is the controller considered read-only because it's under the | |||
// control of the platform. In the case of Kibernetes, we simply |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
cluster/cluster.go
Outdated
// Is the controller considered read-only because it's under the | ||
// control of the platform. In the case of Kibernetes, we simply | ||
// omit these controllers; but this may not always be the case. | ||
IsSystem bool |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
api/v6/api.go
Outdated
type ControllerStatus struct { | ||
ID flux.ResourceID | ||
Containers []Container | ||
ReadOnly ReadOnlyReason `json:",omitempty"` |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
err = d.WithClone(ctx, func(checkout *git.Checkout) error { | ||
var err error | ||
services, err = d.Manifests.ServicesWithPolicies(checkout.ManifestDir()) | ||
return err | ||
}) | ||
if err != nil { | ||
switch { |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
daemon/daemon.go
Outdated
return nil, errors.Wrap(err, "getting service policies") | ||
} | ||
|
||
var res []v6.ControllerStatus | ||
for _, service := range clusterServices { | ||
policies := services[service.ID] | ||
var readonly v6.ReadOnlyReason |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
@@ -21,7 +21,7 @@ const ( | |||
var ( | |||
ErrNoChanges = errors.New("no changes made in repo") | |||
ErrNotReady = errors.New("git repo not ready") | |||
ErrNoConfig = errors.New("git repo has not valid config") | |||
ErrNoConfig = errors.New("git repo does not have valid config") |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
Should we wait until we're ready to do a |
Instead of waiting for the git repo to be cloned and ready, just start the mirror going and be prepared for some operations to fail. This is the first step towards operating without a git repo; the second is to change (some) API responses depending on whether a git repo is present, rather than failing when it's not.
Of the API methods, ListControllers is the only one for which a git repo is optional; make it return a response with less information, rather than an error, if the repo is not ready. Some other methods either don't try to look at the repo (ListImages), in which case no change is needed. The remainder refer to the repo (usually because they want to write to it), so must return an error. That will happen as things stand, since attempting to clone the repo results in an error.
Some controllers will be effectively read-only, because - they are under control of the system (e.g., addons) - they don't appear in the git repo, so we can't write changes - the git repo isn't ready, or hasn't been supplied So that we can treat these specially, mark them as read-only in the ListServices API result. On backwards compatibility: I have added this into the v6 API, because it's a hint to the API client; the zero value indicates it is _probably_ OK to attempt whatever you want to attempt. Since prior daemon code wouldn't proceed if the git repo wasn't ready, that is more often than not the case.
1b4dfff
to
8f8dc0c
Compare
I reckon we can do a release in the meantime. |
The *git.Repo state machine has a state for `RepoNoConfig` (meaning no repo URL supplied), but hitherto it was not reachable, because the constructor initialised the state to `RepoNew` (not cloned yet), and there is no transition from there to `RepoNoConfig`. We do want to distinguish the "no config" state from just not being ready, however. This commit makes the state reachable, and accounts for it in *git.Repo methods. Ultimately this is visible via the API, where "no config" is now treated as a reason for ListController results to be read-only.
We let main() exit, and block on graceful shutdown in a `defer`ed procedure. We _also_ `defer` a call to `upstream.Close()`, which stops the upstream reconnecting and closes it. The two deferred procedure calls used to be in such an order that by coincidence, `upstream.Close()` was _also_ blocked on graceful shutdown. But this order was shuffled in PR #962. This commit makes the `upstream.Close()` explicitly wait for shutdown.
We let main() exit, and block on graceful shutdown in a `defer`ed procedure. We _also_ `defer` a call to `upstream.Close()`, which stops the upstream reconnecting and closes it. The two deferred procedure calls used to be in such an order that by coincidence, `upstream.Close()` was _also_ blocked on graceful shutdown. But this order was shuffled in PR #962. This commit makes the `upstream.Close()` explicitly wait for shutdown.
Instead of waiting for the git repo to be ready before responding to API calls (aside from status), just start the repo syncing when starting up, and respond according to its current state.
The API (ListServices) will now mark controllers that aren't in the git repo -- or all controllers if there's no git repo -- as being read-only, supplying a reason in the field
ReadOnly
. An empty field indicates that the controller is (probably) writable. Old daemons won't populate this field, but since they don't answer ListServices until the repo is ready anyway, the assumption that the controller is writable will still usually be correct (and not disastrous when it's wrong).An example API response: