Operator sync resurrected #809
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Last night I wrote down some ideas I have for operator sync. After reading through existing conversations (toolshed/organising#467, #457 and more) I am happy to see it aligns and overlaps well with existing ideas as well as addressing some of the concerns.
Differences to previous proposals
The initial implementation would be automatic but also fully opt-in. To enable operator sync, you will need
your env files within a git repo (its root can be anywhere) and have a remote calledto addoperator-sync. Opting in/out is as simple as renaming the git remote and can be done individually.sync: truetoabra.yml.The other main difference to existing ideas would be to commit&push only and all changes to server side state (even if no files have changed, creating empty commits) which would make the git log work as an operator log.
Initial implementation
Operator sync is activated if the server dir is part of a git repo and it has a remote called
operator-sync.Operator sync would function automatically on
abra appcommands in two different ways:Commands modifying server state
Commands which modify the server state should
theoperator-syncremote withgit pull --rebasebehaviour--no-operator-sync.envfile of the app in questiontooperator-syncremoteCommands with this behaviour would be the following
abra appcommands:deploymovenew --secretsremoverestorerollbacksecret generate/insert/removeundeployupgradevolume removeThis might lead to seemingly weird side effects like that the commit with
secret insertwill add the.envof a new app. I think that is correct though as this is exactly the point where the something about this app is created on the server.To only commit the
<domain>.envin question will prevent unintended side effects. A warning about other changed files should help you keep the repo clean. If you added other files related to this app you might want to commit them manually. I am not quite sure how to deal with staged changes yet.git pull --rebasebehaviour should reduce the amount of manual intervention needed to a minimum. In these cases intervention is probably needed anyway.Some others are also (potentially) modifying server state (
command,restart, ...), though I consider not important enough to keep a log of. I might have missed smth though!Other
abra appcommandsEvery other
abra appcommand should execute the pull-part only - they all depend on the list of services. In this case a pull failure could be a non-fatal error. Though you might miss that in the wall of text that the command probably produces.I do not envision creating new abra commands initially and would like it to work as automatic as possible after setup. I think we can also rely on operators' ability to use
gitif anything breaks.Other considerations
Since every app command is now pulling the remote, this might slow down operations. To mitigate
abracould somehow take note of the last successful pull and only pull again after a few minutes or so.To override behaviour, I envision these flags:
--no-operator-syncdo not do pulls and pushes--offlineshould be respected--no-operator-logdo not create git commit (implies--no-operator-sync)--force-syncalways pull on commands without cooldownI tend to think a bit far sometimes and I recognize that this might be a bit much for an initial implementation. Implementing only part of this could be helpful already.
Future possibilities
This may be a bit far off right now, I just want to get it out of my head. If initial implementation turns out to be useful, further steps could include:
abra.ymloptions to change sync/log behaviourabra server add<server>:~/.abra/operator-sync.gitPlease leave comments on what you think of this!
I'm all for this approach. Thanks for drawing it up! If it's something people can slowly opt-in to and we can fix as we go without some big breaking migration then I think it's doable. It's more a question for me of how to break this down into some logical order of bit-by-bit implementation that we can roll out and have people test.
I think we will have to invest in making sure we can somehow cover all the failure scenarios of Swarm deployments and that they are reflected in the env version. I feel like we are still building on shaky foundations. #808 shows the current limitations and I'm not sure what to do about it.
@iexos How would this work if we already work in a git repo? Could you describe that use case? Like how would this interact with normal git usage?
@p4u1
Assuming you have repo with a single remote
origin, you will have to rename that remote tooperator-sync. You can continue to use the repo as before.Now when using any
abra appcmd this repo will be pulled.Additionally, any time you execute one of the server-modifying cmds above like
abra app deploy <domain>a commit will be created in which only changes to<domain>.envare added. Then the repo is pushed to remote.So what you potentially need to watch out for is that all commits made before will also be pushed and that the
.envfile will be committed.Also, your git log will likely grow much faster.
Hmmm good question. Being required to
git remote rename origin operator-syncis kind of breaking an existing workflow? I had actually imagined it being a 2nd remote that you add alongsideorigin(which also seems weird now that I type it out). Another possibility is triggering via a config value so that you can keep the same git remote name?Both can be possible, either renaming or adding the remote. I thought if only one remote is present, cmds like pull, push will continue to work as normal but maybe that is wrong?
Where I come from is that the double remotes of recipes (
origin&origin-ssh) confuse my shell prompt as it thinks origin is not up-to-date because abra pushes the other one, showing me unpushed commits. But if that is no issue for you then just use both.I would really prefer enabling via got config instead of an implicit got remote name. I was also confused if I would have two remotes then.
Another scenario:
What happens if I have local changes? Then git pull will error. Would Abra then run git stash and then git pull and then got stash pop? This would increase possibilities for errors.
Then lets enable sync via config file then, you are right it might be more clear.
I also checked the
git pullbehaviour. I seem to have remembered it wrong, without--rebaseit will sync even if there are changes in the repo if the same file is not modified both remote and local and with--rebaseit won't sync. So I would prefer without--rebasethen.As to breaking down the implementation into smaller steps, I would go with (order not that important):
sync: trueoptiongit pullbefore running anyabra appcmddeploy&upgradeNice!
I'm fine with just bailing out explicitly on
git pullfailures, showing the diff/failure logs and asking to resolve stuff manually. It will be easier to see then the ways operators trip each other up and how we can give some guidelines for the social side of this new change.This is gonna create a tonne of mind bending scenarios when it doesn't do what you expected. We'll just have to form a tight alpha testing group and see it through with all the bugs and twists and turns 🫡
Great plan! Some thoughts on the faster-growing log: It would be helpful if multiple config changes that relate to each other could be included in a single commit, with a custom summary message. For example
I think this could be achieved by amending commits. Manually by adding something like
--amend-to-last-commitor automatically with a configtimewindow-commit-amend: 120 minutes.Any command that would commit something, then checks if the last commit was made by the current user and if it is within the configured time window for amending. If so, use
git commit --amend -m "Updated message" & git push --force-with-leaseinstead of (and when failing, fallback to) pushing a new commit. In these cases, abra could also ask to add or update the summary message for these commits; or run a separate abra command or manual git amend when you're done to amend a custom summary message.Or instead of putting this in the abra config, there could be
abra operatorsync starttransaction -m "Summary of what I'm going to do" -t 120. That creates a commit with the summary message, stores the specified time window somewhere and uses the logic of the previous paragraph to amend all config changes to this commit.@dannygroenewegen If I understand your proposal correctly, this will make sure that no other pushed changes are overridden. But that would mean if you are pulling from another machine in the meantime you will have to deal with a conflict when upstream history changed? While abra could theoretically deal with that as well, it would make things quite complex.
There's indeed a changed upstream history, but I don't think that creates a new problem:
git pullhas no problem updating to the changed upstream history.git pullwill update the changed history and the uncommitted changes are kept.git pullat the start of an abra command will fail due to conflicting uncommitted changes. This means two people are working on the same thing, which I think is a valid reason to require manual resolving.git pull --rebaseI would argue that these merge conflicts are not caused by amended commits, but by two people working on the same files at the same time. And I think these conflicts could also happen without amended commits, so abra would have to deal with this anyway by solving or providing useful errors.
If it really works without additional trouble, it could be nice to explore. I personally don't really see a need for this (yet) and would not do it for the initial implementation but we can keep it in mind if the need comes up. Thank you for your input!