remove-backup (client version 2.4) doesn't work on a 2.3 controller
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Canonical Juju |
Triaged
|
Low
|
Unassigned |
Bug Description
Hi,
Using a 2.4 client on a 2.3 controller, remove-backup produces the following :
$ juju backups
20180518-
20180628-
$ juju remove-backup --debug 20180518-
10:20:44 INFO juju.cmd supercommand.go:56 running juju [2.4.1 gc go1.10]
10:20:44 DEBUG juju.cmd supercommand.go:57 args: []string{"juju", "remove-backup", "--debug", "20180518-
[irrelevant stuff]
10:20:45 DEBUG juju.api monitor.go:35 RPC connection died
ERROR expected 1 result(s), got 0
10:20:45 DEBUG cmd supercommand.go:459 error stack:
github.
github.
However, the same "remove-backup" above works fine with a 2.3 client.
Thanks
Changed in juju: | |
milestone: | 2.4.3 → none |
Changed in juju: | |
milestone: | none → 2.4.4 |
Changed in juju: | |
milestone: | 2.4.4 → none |
in 2.4 it looks like we added API version 2 which allows you to pass >1 backup to remove. ErrorResult, error) { ErrorResult{ }, nil BackupsRemoveAr gs{IDs: ids} ErrorResults{ } FacadeCall( "Remove" , args, &results) Results) != len(ids) { Results) ,
However, it seems the 2.4 client always assumes a 2.4 server:
The client side code calls Remove, doesn't pay attention to the facade version and assumes len(results) == len(ids):
func (c *Client) Remove(ids ...string) ([]params.
if len(ids) == 0 {
return []params.
}
args := params.
results := params.
err := c.facade.
if len(results.
return nil, errors.Errorf(
"expected %d result(s), got %d",
len(ids), len(results.
)
}
return results.Results, errors.Trace(err)
}
However, it the 2.3 server it does:
func (a *API) Remove(args params. BackupsRemoveAr gs) error { a.backend)
backups, closer := newBackups(
defer closer.Close()
err := backups. Remove( args.ID)
return errors.Trace(err)
}
(it only allows 1 Id in BackupRemoveArgs and it returns any error as the overall error for the function call.)
The server side implementing V2 is doing a good thing (allowing you to pass >1 argument, returning multiple possible error codes, etc.)
However, the new client needs to stay compatible with the old servers. It should have code something like:
if len(ids) == 0 { ErrorResult{ }, nil BestAPIVersion( ) < 2 { Errorf( "server does not support removing >1 backup at a time, please pass only a single value") BackupsRemoveAr gs{ID: ids[0]} FacadeCall( "Remove" , args, nil) ErrorResult? BackupsRemoveAr gs{IDs: ids} ErrorResults{ } FacadeCall( "Remove" , args, &results) Results) != len(ids) { Results) ,
return []params.
}
if c.facade.
// In version 2 we introduced multiple IDs that can be removed at the same time, prior versions only supported 1 backup to remove
if len(ids) > 1 {
return nil, errors.
}
args := params.
err := c.facade.
// Do we turn this into a []params.
return nil, err
}
args := params.
results := params.
err := c.facade.
if len(results.
return nil, errors.Errorf(
"expected %d result(s), got %d",
len(ids), len(results.
)
}
return results.Results, errors.Trace(err)