That's odd. At least from what I can see in the Juju code, there are no checks for otherEnd's scope and there are watchers for different relation objects.
If this end is global - should send
If this end is not global - check if the other end is a principal for this watcher - should send
If this end is not global and the other end is not a principal - should send (subordinate <-> subordinate)
// Only allow container relations if the other end is our
// principal or the other end is a subordinate.
otherEnds, err := rel.RelatedEndpoints(w.app.Name())
if err != nil {
return false, errors.Trace(err)
}
for _, otherEnd := range otherEnds {
if otherEnd.ApplicationName == w.principalName {
return true, nil
}
otherApp, err := w.backend.Application(otherEnd.ApplicationName)
if err != nil {
return false, errors.Trace(err)
}
if !otherApp.IsPrincipal() {
return true, nil
}
}
This behavior of setting relation scope to 'container' if one of two sides has ScopeContainer goes way back (to 5 years ago): https://github.com/juju/juju/blame/juju-2.2.4/state/state.go#L1661-L1668
func (st *State) AddRelation(eps ...Endpoint) (r *Relation, err error) {
...
// If either endpoint has container scope, so must the other; and the
// applications's series must also match, because they'll be deployed to
// the same machines.
matchSeries := true
if eps[0].Scope == charm.ScopeContainer {
eps[1].Scope = charm.ScopeContainer
} else if eps[1].Scope == charm.ScopeContainer {
eps[0].Scope = charm.ScopeContainer
~stub,
That's odd. At least from what I can see in the Juju code, there are no checks for otherEnd's scope and there are watchers for different relation objects.
If this end is global - should send
If this end is not global - check if the other end is a principal for this watcher - should send
If this end is not global and the other end is not a principal - should send (subordinate <-> subordinate)
https:/ /github. com/juju/ juju/blob/ juju-2. 2.4/apiserver/ uniter/ subordinaterela tionwatcher. go#L118- L139 tcher) shouldSendCheck(key string) (bool, error) {
func (w *subRelationsWa
...
if thisEnd.Scope == charm.ScopeGlobal {
return true, nil
}
// Only allow container relations if the other end is our oints(w. app.Name( )) ApplicationName == w.principalName { Application( otherEnd. ApplicationName ) IsPrincipal( ) {
// principal or the other end is a subordinate.
otherEnds, err := rel.RelatedEndp
if err != nil {
return false, errors.Trace(err)
}
for _, otherEnd := range otherEnds {
if otherEnd.
return true, nil
}
otherApp, err := w.backend.
if err != nil {
return false, errors.Trace(err)
}
if !otherApp.
return true, nil
}
}
No checks for scope here either: /github. com/juju/ juju/blob/ juju-2. 2.4/apiserver/ uniter/ uniter. go#L1691- L1705
https:/
This behavior of setting relation scope to 'container' if one of two sides has ScopeContainer goes way back (to 5 years ago): /github. com/juju/ juju/blame/ juju-2. 2.4/state/ state.go# L1661-L1668 ainer { ainer ainer { ainer
https:/
func (st *State) AddRelation(eps ...Endpoint) (r *Relation, err error) {
...
// If either endpoint has container scope, so must the other; and the
// applications's series must also match, because they'll be deployed to
// the same machines.
matchSeries := true
if eps[0].Scope == charm.ScopeCont
eps[1].Scope = charm.ScopeCont
} else if eps[1].Scope == charm.ScopeCont
eps[0].Scope = charm.ScopeCont
eps ~ Endpoint ~ Relation /github. com/juju/ juju/blob/ juju-2. 2.4/api/ uniter/ endpoint. go#L13- L15 /github. com/juju/ charm/blob/ v6-unstable/ meta.go# L125-L134
https:/
Relation
https:/
---
Which Juju version was used when you noticed the undefined behavior with one side Global and another side Container-scoped?