Remodeling to a new model

upcoming
pedronis

#1

As we planned in Opt-in accepting/distribution of 'generic'-signed serials registration should always send both the model assertion of the device and a serial request assertion.

A remodeling operation can be used to move a device – with a model and registered for it – to a new model.

Before the device can acquire a new store session to access the potentially new brand store as the new model, it needs to register itself as the new model.

For a first iteration of this we will assume that the new model registration is served by the same device service (aka serial vault) as the current model.

The device, early as part of the whole remodeling, will proceed with a new registration by sending a serial-request with extra fields:

  • original-brand-id
  • original-model
  • original-serial

It will also send the new model assertion as well as the current serial assertion.

For this it will use the same configuration as if for the original serial request, kept as gadget configuration, at this point it doesn’t have yet access to the new gadget.

Based on its own configuration and the information sent by the remodeling device, after cross checking it, the device service will determine whether to allow the remodel and issue back a serial for the new model.


#2

Now on a device that went through a remodeling (or multiple) to new brand/model there will be multiple model and serial assertions in its system assertion database. This means that snap known model|serial alone cannot answer what is the current model/serial of the device.

We will introduce dedicated commands to find the current model/serial of a device:

snap model [--serial]  [--verbose|--assertion]

The basic commands will display what are the primary keys of the underlying assertions in the usual YAML-like format. With --verbose all information (except assertion details) will be printed. With --assertion the commands will output the underlying assertion verbatim.

The snapd API behind these will work similarly to /v2/assertions/{assertType}][?json=] but returning only the current assertion and living at /v2/model and /v2/model/serial respectively.


#3

snap model [--serial] have landed on master but the differences between the two (in not --verbose|--assertion mode) don’t bring a lot of value, it’s almost tempting to always use snap model --serial except is longer and can fail in more cases, and both are slightly more machine oriented than human oriented. Let’s rework them to make always using snap model in the basic case the right thing for an operator. Let’s also consider the error cases for when assertions (either model or serial) are not found:

  • If there is no model (this also the output for --verbose/--assertion):
    $ snap model
    error: device not ready yet (no assertions found)
    
  • If there is a model but no serial (notice, here we follow the style of snap version basically):
    $snap model
    brand  Canonical✓          //// publisher style account display
    model  generic-classic     //// either <model header> OR if set: <model display-name header> (<model header>)
    serial - (device not registered yet)
    
  • If there is a model and serial, same but display also serial (same consideration vs snap version):
    $snap model
    brand  Canonical✓          //// publisher style account display
    model  generic-classic     //// either <model header> OR if set:  <model display-name header> (model header)
    serial SERIAL              //// <serial header>
    

For snap model --serial:

  • If there is no model (this also the output for --verbose/--assertion):
    $ snap model  --serial
    error: device not ready yet (no assertions found)
    
  • If there is a model but no serial (this is an error case, this is the output also for --verbose for this case):
    $snap model --serial
    brand-id: canonical         //// to stdout
    model:    generic-classic   //// to stdout
    error: device not registered yet (no serial assertion found)
    
    the output is just the latter error line for --assertion!!
  • If there is a serial (and so a model), output is like current master:
    $ snap model --serial
    brand-id: canonical
    model:    generic-classic
    serial:   SERIAL
    

To implement these we will need client.StoreAccount(accountID string) (*snap.StoreAccount, error), this doesn’t need a new endpoint tough, it can use the assertions one.


#4

This wasn’t clear, but should we also output serial when the user runs snap model --verbose (outputting - if they don’t have a serial assertion and a real serial if they have one)?

I assumed yes, and that’s what I’ve got implemented now.


#5

Also, I’m wondering if the /v2/model and /v2/model/serial endpoints should include an X-Ubuntu-Assertions-Count header in the HTTP response? It’s not really necessary since these endpoints by design will always return a single assertion, but maybe we still want that header for consistency with the assertions endpoint.


#6

wouldn’t say so, it’s a bit of a historical oddity anyway, also the count is expected to be 1 here on success