-
Notifications
You must be signed in to change notification settings - Fork 566
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
many: abbreviated forms of disconnect #2066
Changes from 20 commits
d02b967
47a5852
982d086
e7ba90c
7ddcd7f
c1805ec
faf4b63
ec4bcae
b44bb08
ea0ee46
e9c2293
3e9348a
a6f36a8
6eefa28
612cc30
f6101eb
1ba25f2
aae93f1
853b227
fd17380
7b9b6de
fc5233a
5354595
d496ce0
dc380e4
1c0ff1f
1a1f189
9bb858f
e34153d
3f88492
f653e81
3a3bc02
98e974c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,13 +39,10 @@ $ snap disconnect <snap>:<plug> <snap>:<slot> | |
|
||
Disconnects the specific plug from the specific slot. | ||
|
||
$ snap disconnect <snap>:<slot> | ||
$ snap disconnect <snap>:<slot or plug> | ||
|
||
Disconnects any previously connected plugs from the provided slot. | ||
|
||
$ snap disconnect <snap> | ||
|
||
Disconnects all plugs from the provided snap. | ||
Disconnects everything from the provided plug or slot. | ||
The snap name may be omitted for the OS snap. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/OS snap/core snap/ |
||
|
||
Application Options: | ||
--version Print the version and exit | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -327,68 +327,182 @@ func (r *Repository) Connect(ref ConnRef) error { | |
// from all the slots found therein. It is not an error if there are no | ||
// such plugs but it is still an error if the snap does not exist or has no | ||
// slots at all. | ||
func (r *Repository) Disconnect(plugSnapName, plugName, slotSnapName, slotName string) error { | ||
// | ||
// Disconnect returns the list of severed connections, the list of affected snaps | ||
// and an error if one occurred. | ||
func (r *Repository) Disconnect(plugSnapName, plugName, slotSnapName, slotName string) ([]ConnRef, []*snap.Info, error) { | ||
r.m.Lock() | ||
defer r.m.Unlock() | ||
|
||
var conns []ConnRef | ||
var snaps map[string]*snap.Info | ||
var err error | ||
|
||
switch { | ||
case plugSnapName == "" && plugName == "" && slotName == "": | ||
// Disconnect everything from slotSnapName | ||
return r.disconnectEverythingFromSnap(slotSnapName) | ||
case plugSnapName == "" && plugName == "": | ||
// Disconnect everything from slotSnapName:slotName | ||
return r.disconnectEverythingFromSlot(slotSnapName, slotName) | ||
// Disconnect everything from either slot or plug | ||
conns, snaps, err = r.disconnectPlugOrSlot(slotSnapName, slotName) | ||
default: | ||
return r.disconnectPlugFromSlot(plugSnapName, plugName, slotSnapName, slotName) | ||
conns, snaps, err = r.disconnectPlugFromSlot(plugSnapName, plugName, slotSnapName, slotName) | ||
} | ||
|
||
if err != nil { | ||
return nil, nil, err | ||
} | ||
// Flatten map of snaps into a sorted list | ||
names := make([]string, 0, len(snaps)) | ||
for snapName := range snaps { | ||
names = append(names, snapName) | ||
} | ||
sort.Strings(names) | ||
result := make([]*snap.Info, 0, len(snaps)) | ||
for _, snapName := range names { | ||
result = append(result, snaps[snapName]) | ||
} | ||
return conns, result, nil | ||
} | ||
|
||
// disconnectEverythingFromSnap finds a specific snap and disconnects all the plugs connected to all the slots therein. | ||
func (r *Repository) disconnectEverythingFromSnap(slotSnapName string) error { | ||
if _, ok := r.slots[slotSnapName]; !ok { | ||
return fmt.Errorf("cannot disconnect plug from snap %q, no such snap", slotSnapName) | ||
// ResolveDisconnectAll finds all of the connections that would be disconnected by DisconnectAll() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds strange. It's this function that defines what DisconnectAll should disconnect, not the other way around. Suggestion for rename and documentation:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
func (r *Repository) ResolveDisconnectAll(snapName, plugOrSlotName string) ([]ConnRef, error) { | ||
r.m.Lock() | ||
defer r.m.Unlock() | ||
|
||
return r.unlockedResolveDisconnectAll(snapName, plugOrSlotName) | ||
} | ||
|
||
func (r *Repository) unlockedResolveDisconnectAll(snapName, plugOrSlotName string) ([]ConnRef, error) { | ||
if snapName == "" { | ||
// Look up the core snap if no snap name was given | ||
switch { | ||
case r.slots["core"] != nil: | ||
snapName = "core" | ||
case r.slots["ubuntu-core"] != nil: | ||
snapName = "ubuntu-core" | ||
default: | ||
return nil, fmt.Errorf("cannot resolve disconnect, snap name is empty") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/cannot resolve disconnect, // (not a disconnection in this context) |
||
} | ||
} | ||
for _, slot := range r.slots[slotSnapName] { | ||
for plug := range r.slotPlugs[slot] { | ||
var conns []ConnRef | ||
if plugOrSlotName == "" { | ||
// "wildcard" mode, affect all the plugs or slots in this snap | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have any real use cases for this today? We don't want this in the CLI, so if there are no other use cases we should probably just error for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't seem that we do. I've simplified the code and removed this case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed and simplified |
||
for _, plug := range r.plugs[snapName] { | ||
for _, slotRef := range plug.Connections { | ||
connRef := ConnRef{PlugRef: plug.Ref(), SlotRef: slotRef} | ||
conns = append(conns, connRef) | ||
} | ||
} | ||
for _, slot := range r.slots[snapName] { | ||
for _, plugRef := range slot.Connections { | ||
connRef := ConnRef{PlugRef: plugRef, SlotRef: slot.Ref()} | ||
conns = append(conns, connRef) | ||
} | ||
} | ||
} else { | ||
// Precise mode, affect specific plug or slot in this snap | ||
if plug, ok := r.plugs[snapName][plugOrSlotName]; ok { | ||
for _, slotRef := range plug.Connections { | ||
connRef := ConnRef{PlugRef: plug.Ref(), SlotRef: slotRef} | ||
conns = append(conns, connRef) | ||
} | ||
} | ||
if slot, ok := r.slots[snapName][plugOrSlotName]; ok { | ||
for _, plugRef := range slot.Connections { | ||
connRef := ConnRef{PlugRef: plugRef, SlotRef: slot.Ref()} | ||
conns = append(conns, connRef) | ||
} | ||
} | ||
// Check if plugOrSlotName actually maps to anything | ||
if len(conns) == 0 { | ||
return nil, fmt.Errorf("snap %q has no plug or slot named %q", snapName, plugOrSlotName) | ||
} | ||
} | ||
return conns, nil | ||
} | ||
|
||
// DisconnectAll disconnects all of the given connections, returning the list of affected snap names. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we returning a list of snap names? We asked the repository itself to resolve the list of affected connections for us, so we already have it at hand are actually handing it in. Feels strange to get this list out from this function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, we don't have to get this back from the function. I was just transcribing things mechanically. I'll get rid of it and move the relevant logic to ifacestate where we actually need it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also simplified |
||
func (r *Repository) DisconnectAll(conns []ConnRef) []string { | ||
r.m.Lock() | ||
defer r.m.Unlock() | ||
|
||
// Sever all the connections, keeping track of affected snaps | ||
snaps := make(map[string]bool) | ||
for _, conn := range conns { | ||
plug := r.plugs[conn.PlugRef.Snap][conn.PlugRef.Name] | ||
slot := r.slots[conn.SlotRef.Snap][conn.SlotRef.Name] | ||
if plug != nil && slot != nil { | ||
snaps[plug.Snap.Name()] = true | ||
snaps[slot.Snap.Name()] = true | ||
r.disconnect(plug, slot) | ||
} | ||
} | ||
return nil | ||
// Flatten map of affected snaps into a sorted list | ||
names := make([]string, 0, len(snaps)) | ||
for snapName := range snaps { | ||
names = append(names, snapName) | ||
} | ||
sort.Strings(names) | ||
return names | ||
} | ||
|
||
// disconnectEverythingFromSlot finds a specific slot and disconnects all the plugs connected there. | ||
func (r *Repository) disconnectEverythingFromSlot(slotSnapName, slotName string) error { | ||
// Ensure that such slot exists | ||
slot := r.slots[slotSnapName][slotName] | ||
if slot == nil { | ||
return fmt.Errorf("cannot disconnect plug from slot %q from snap %q, no such slot", slotName, slotSnapName) | ||
func (r *Repository) disconnectPlugOrSlot(snapName, plugOrSlotName string) ([]ConnRef, map[string]*snap.Info, error) { | ||
if snapName == "" { | ||
// TODO: teach the repository about the OS snap | ||
snapName = "ubuntu-core" | ||
} | ||
|
||
if r.slots[snapName][plugOrSlotName] == nil && r.plugs[snapName][plugOrSlotName] == nil { | ||
err := fmt.Errorf("cannot disconnect plug or slot %q from snap %q, no such plug/slot", plugOrSlotName, snapName) | ||
return nil, nil, err | ||
} | ||
for plug := range r.slotPlugs[slot] { | ||
|
||
var conns []ConnRef | ||
snaps := make(map[string]*snap.Info) | ||
d := func(plug *Plug, slot *Slot) { | ||
r.disconnect(plug, slot) | ||
snaps[plug.Snap.Name()] = plug.Snap | ||
snaps[slot.Snap.Name()] = slot.Snap | ||
conns = append(conns, ConnRef{PlugRef: plug.Ref(), SlotRef: slot.Ref()}) | ||
} | ||
return nil | ||
if slot := r.slots[snapName][plugOrSlotName]; slot != nil { | ||
for plug := range r.slotPlugs[slot] { | ||
d(plug, slot) | ||
} | ||
} | ||
if plug := r.plugs[snapName][plugOrSlotName]; plug != nil { | ||
for slot := range r.plugSlots[plug] { | ||
d(plug, slot) | ||
} | ||
} | ||
return conns, snaps, nil | ||
} | ||
|
||
// disconnectPlugFromSlot finds a specific slot and plug and disconnects it. | ||
func (r *Repository) disconnectPlugFromSlot(plugSnapName, plugName, slotSnapName, slotName string) error { | ||
// disconnectPlugFromSlot finds a specific plug slot and plug and disconnects it. | ||
func (r *Repository) disconnectPlugFromSlot(plugSnapName, plugName, slotSnapName, slotName string) ([]ConnRef, map[string]*snap.Info, error) { | ||
// Ensure that such plug exists | ||
plug := r.plugs[plugSnapName][plugName] | ||
if plug == nil { | ||
return fmt.Errorf("cannot disconnect plug %q from snap %q, no such plug", plugName, plugSnapName) | ||
err := fmt.Errorf("cannot disconnect plug %q from snap %q, no such plug", plugName, plugSnapName) | ||
return nil, nil, err | ||
} | ||
// Ensure that such slot exists | ||
slot := r.slots[slotSnapName][slotName] | ||
if slot == nil { | ||
return fmt.Errorf("cannot disconnect plug from slot %q from snap %q, no such slot", slotName, slotSnapName) | ||
err := fmt.Errorf("cannot disconnect plug from slot %q from snap %q, no such slot", slotName, slotSnapName) | ||
return nil, nil, err | ||
} | ||
// Ensure that slot and plug are connected | ||
if !r.slotPlugs[slot][plug] { | ||
return fmt.Errorf("cannot disconnect plug %q from snap %q from slot %q from snap %q, it is not connected", | ||
err := fmt.Errorf("cannot disconnect plug %q from snap %q from slot %q from snap %q, it is not connected", | ||
plugName, plugSnapName, slotName, slotSnapName) | ||
return nil, nil, err | ||
} | ||
r.disconnect(plug, slot) | ||
return nil | ||
conns := []ConnRef{{PlugRef: plug.Ref(), SlotRef: slot.Ref()}} | ||
snaps := map[string]*snap.Info{ | ||
plug.Snap.Name(): plug.Snap, | ||
slot.Snap.Name(): slot.Snap, | ||
} | ||
return conns, snaps, nil | ||
} | ||
|
||
// disconnect disconnects a plug from a slot. | ||
|
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.
s/OS snap/core snap/