# Progress status sync
## Related comments
### Comment #1
>Can we qualify "consistent UX"?
Does it mean that an upgrade will be triggered the same way no matter the upgrade strategy?
Does it mean that upgrade progress will be always represented in the same way?
My idea: For rollout upgrade, capi creates new machine with latest infra spec, bootstrap config and version. Then KCP/MD iterate machines and update status (replicas, updatedReplicas, readyReplicas) and MachinesSpecUpToDateCondition to reflect update progress. If we want to claim consistent UX for progress, then there should be many things to do on MD/KCP CR side.
### Comment #2
>I don't think that delegating to the external reconcilers the task to upgrade status is ideal for a couple of reasons.
The most important is that this approach implies that each external upgrader needs to know all the internals of KCP, MD (MP) and to implement the code to report status back.
This not only leads to duplication of efforts but it also introduce the risks that external upgrader will report status back in the wrong way, eventually leading to CAPI failures.
I think we should rethink this part and envision a flow where CAPI queries the external upgrader for progress updates, and then updates its own status
My idea: Indeed, update machine condition is not enough, as mentioned above, kcp/md CR shall also be updated. So, maybe we shall consider to have a contract to let external to talk to kcp/md, and let kcp/md controller to implement status update.
### Comment #3
>I would prefer to not have external components to set conditions on the CAPI objects, also because in most cases acting on the machines is simply not enough (thing e.g to MS and machines)
My idea: I didn't find any existing use case in CAPI which let external to manipulate conditions. Well, I see some some capi features which relies on annotation to communicate with external.
### Comment #4
>If I look at this as a user, this seems really confusing and error-prone.
It probably requires some more considerations.
My idea: Same as #2, better let capi to change machine/infraMachine
## Update progress sync
### Component interaction sequence diagram
```plantuml
@startuml
actor User as user
participant "CAPI" as capi
participant "External Updater" as ex
participant "ControlPlane" as cp
user -> capi: upgrade k8s version
capi -> ex: call Lifecycle Runtime Hook \n**ExternalUpgradeRequest**
ex --> capi: accept
loop
ex -> cp: set external update progress\nannotation on CP
note right
cluster.x-k8s.io/external-update="
{
machine1: {state:complete},
machine2: {state:inprogress,severity:warning,
message: 'retry connecting host'},
machine3: {state:waiting},
}"
end note
cp -> cp: set machine progress
note right
1. find machine CR, update bootstrap & version
2. find infraMachine CR, update infraSpec
end note
cp -> cp: set Controlplane progress
note right
update status updatedReplicas,
and MachinesSpecUpToDateCondition
end note
end loop
@enduml
```
1. external updater sync progress through annotation `cluster.x-k8s.io/external-update`
2. let cp/md controller implement progress sync according the status info in annotation
### Advantages:
- offload logic from external updater to capi, so that external updater don't need have deep knowledge on capi crs, reduce complexlity and less error prone
- cp/md implemenation can make sure the progress of update is consistent with rolling update
- no need to introduce new condition