omaha: split request and response structures
Despite having common names between the request and response XML structures the actual values which may appear in them are completely disjoint. Splitting the types up makes the protocol easier to understand when reading the code. When applicable, required fields like status are passed to Add* methods.
This commit is contained in:
parent
ec70842bdd
commit
75a1125f53
2 changed files with 101 additions and 61 deletions
|
@ -28,19 +28,20 @@ import (
|
||||||
"github.com/coreos/mantle/version"
|
"github.com/coreos/mantle/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Request sent by the Omaha client
|
||||||
type Request struct {
|
type Request struct {
|
||||||
XMLName xml.Name `xml:"request" json:"-"`
|
XMLName xml.Name `xml:"request" json:"-"`
|
||||||
OS *OS `xml:"os"`
|
OS *OS `xml:"os"`
|
||||||
Apps []*App `xml:"app"`
|
Apps []*AppRequest `xml:"app"`
|
||||||
Protocol string `xml:"protocol,attr"`
|
Protocol string `xml:"protocol,attr"`
|
||||||
Version string `xml:"version,attr,omitempty"`
|
Version string `xml:"version,attr,omitempty"`
|
||||||
IsMachine string `xml:"ismachine,attr,omitempty"`
|
IsMachine string `xml:"ismachine,attr,omitempty"`
|
||||||
SessionId string `xml:"sessionid,attr,omitempty"`
|
RequestId string `xml:"requestid,attr,omitempty"`
|
||||||
UserId string `xml:"userid,attr,omitempty"`
|
SessionId string `xml:"sessionid,attr,omitempty"`
|
||||||
InstallSource string `xml:"installsource,attr,omitempty"`
|
UserId string `xml:"userid,attr,omitempty"`
|
||||||
TestSource string `xml:"testsource,attr,omitempty"`
|
InstallSource string `xml:"installsource,attr,omitempty"`
|
||||||
RequestId string `xml:"requestid,attr,omitempty"`
|
TestSource string `xml:"testsource,attr,omitempty"`
|
||||||
UpdaterVersion string `xml:"updaterversion,attr,omitempty"`
|
UpdaterVersion string `xml:"updaterversion,attr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRequest() *Request {
|
func NewRequest() *Request {
|
||||||
|
@ -55,18 +56,71 @@ func NewRequest() *Request {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) AddApp(id, version string) *App {
|
func (r *Request) AddApp(id, version string) *AppRequest {
|
||||||
a := &App{Id: id, Version: version}
|
a := &AppRequest{Id: id, Version: version}
|
||||||
r.Apps = append(r.Apps, a)
|
r.Apps = append(r.Apps, a)
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppRequest struct {
|
||||||
|
Ping *PingRequest `xml:"ping"`
|
||||||
|
UpdateCheck *UpdateRequest `xml:"updatecheck"`
|
||||||
|
Events []*EventRequest `xml:"event" json:",omitempty"`
|
||||||
|
Id string `xml:"appid,attr,omitempty"`
|
||||||
|
Version string `xml:"version,attr,omitempty"`
|
||||||
|
NextVersion string `xml:"nextversion,attr,omitempty"`
|
||||||
|
Lang string `xml:"lang,attr,omitempty"`
|
||||||
|
Client string `xml:"client,attr,omitempty"`
|
||||||
|
InstallAge string `xml:"installage,attr,omitempty"`
|
||||||
|
|
||||||
|
// update engine extensions
|
||||||
|
Track string `xml:"track,attr,omitempty"`
|
||||||
|
FromTrack string `xml:"from_track,attr,omitempty"`
|
||||||
|
|
||||||
|
// coreos update engine extensions
|
||||||
|
BootId string `xml:"bootid,attr,omitempty"`
|
||||||
|
MachineID string `xml:"machineid,attr,omitempty"`
|
||||||
|
OEM string `xml:"oem,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AppRequest) AddUpdateCheck() *UpdateRequest {
|
||||||
|
a.UpdateCheck = &UpdateRequest{}
|
||||||
|
return a.UpdateCheck
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AppRequest) AddPing() *PingRequest {
|
||||||
|
a.Ping = new(PingRequest)
|
||||||
|
return a.Ping
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AppRequest) AddEvent() *EventRequest {
|
||||||
|
event := &EventRequest{}
|
||||||
|
a.Events = append(a.Events, event)
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateRequest struct {
|
||||||
|
TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PingRequest struct {
|
||||||
|
LastReportDays string `xml:"r,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventRequest struct {
|
||||||
|
Type EventType `xml:"eventtype,attr"`
|
||||||
|
Result EventResult `xml:"eventresult,attr"`
|
||||||
|
PreviousVersion string `xml:"previousversion,attr,omitempty"`
|
||||||
|
ErrorCode string `xml:"errorcode,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response sent by the Omaha server
|
||||||
type Response struct {
|
type Response struct {
|
||||||
XMLName xml.Name `xml:"response" json:"-"`
|
XMLName xml.Name `xml:"response" json:"-"`
|
||||||
DayStart DayStart `xml:"daystart"`
|
DayStart DayStart `xml:"daystart"`
|
||||||
Apps []*App `xml:"app"`
|
Apps []*AppResponse `xml:"app"`
|
||||||
Protocol string `xml:"protocol,attr"`
|
Protocol string `xml:"protocol,attr"`
|
||||||
Server string `xml:"server,attr"`
|
Server string `xml:"server,attr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResponse() *Response {
|
func NewResponse() *Response {
|
||||||
|
@ -81,58 +135,43 @@ type DayStart struct {
|
||||||
ElapsedSeconds string `xml:"elapsed_seconds,attr"`
|
ElapsedSeconds string `xml:"elapsed_seconds,attr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Response) AddApp(id string, status AppStatus) *App {
|
func (r *Response) AddApp(id string, status AppStatus) *AppResponse {
|
||||||
a := &App{Id: id, Status: status}
|
a := &AppResponse{Id: id, Status: status}
|
||||||
r.Apps = append(r.Apps, a)
|
r.Apps = append(r.Apps, a)
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
type App struct {
|
type AppResponse struct {
|
||||||
Ping *Ping `xml:"ping"`
|
Ping *PingResponse `xml:"ping"`
|
||||||
UpdateCheck *UpdateCheck `xml:"updatecheck"`
|
UpdateCheck *UpdateResponse `xml:"updatecheck"`
|
||||||
Events []*Event `xml:"event" json:",omitempty"`
|
Events []*EventResponse `xml:"event" json:",omitempty"`
|
||||||
Id string `xml:"appid,attr,omitempty"`
|
Id string `xml:"appid,attr,omitempty"`
|
||||||
Version string `xml:"version,attr,omitempty"`
|
Status AppStatus `xml:"status,attr,omitempty"`
|
||||||
NextVersion string `xml:"nextversion,attr,omitempty"`
|
|
||||||
Lang string `xml:"lang,attr,omitempty"`
|
|
||||||
Client string `xml:"client,attr,omitempty"`
|
|
||||||
InstallAge string `xml:"installage,attr,omitempty"`
|
|
||||||
Status AppStatus `xml:"status,attr,omitempty"`
|
|
||||||
|
|
||||||
// update engine extensions
|
|
||||||
Track string `xml:"track,attr,omitempty"`
|
|
||||||
FromTrack string `xml:"from_track,attr,omitempty"`
|
|
||||||
|
|
||||||
// coreos update engine extensions
|
|
||||||
BootId string `xml:"bootid,attr,omitempty"`
|
|
||||||
MachineID string `xml:"machineid,attr,omitempty"`
|
|
||||||
OEM string `xml:"oem,attr,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) AddUpdateCheck() *UpdateCheck {
|
func (a *AppResponse) AddUpdateCheck(status UpdateStatus) *UpdateResponse {
|
||||||
a.UpdateCheck = new(UpdateCheck)
|
a.UpdateCheck = &UpdateResponse{Status: status}
|
||||||
return a.UpdateCheck
|
return a.UpdateCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) AddPing() *Ping {
|
func (a *AppResponse) AddPing() *PingResponse {
|
||||||
a.Ping = new(Ping)
|
a.Ping = &PingResponse{"ok"}
|
||||||
return a.Ping
|
return a.Ping
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) AddEvent() *Event {
|
func (a *AppResponse) AddEvent() *EventResponse {
|
||||||
event := new(Event)
|
event := &EventResponse{"ok"}
|
||||||
a.Events = append(a.Events, event)
|
a.Events = append(a.Events, event)
|
||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateCheck struct {
|
type UpdateResponse struct {
|
||||||
URLs *URLs `xml:"urls"`
|
URLs *URLs `xml:"urls"`
|
||||||
Manifest *Manifest `xml:"manifest"`
|
Manifest *Manifest `xml:"manifest"`
|
||||||
TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
|
Status UpdateStatus `xml:"status,attr,omitempty"`
|
||||||
Status UpdateStatus `xml:"status,attr,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateCheck) AddURL(codebase string) *URL {
|
func (u *UpdateResponse) AddURL(codebase string) *URL {
|
||||||
// An intermediate struct is used instead of a "urls>url" tag simply
|
// An intermediate struct is used instead of a "urls>url" tag simply
|
||||||
// to keep Go from generating <urls></urls> if the list is empty.
|
// to keep Go from generating <urls></urls> if the list is empty.
|
||||||
if u.URLs == nil {
|
if u.URLs == nil {
|
||||||
|
@ -143,14 +182,17 @@ func (u *UpdateCheck) AddURL(codebase string) *URL {
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateCheck) AddManifest(version string) *Manifest {
|
func (u *UpdateResponse) AddManifest(version string) *Manifest {
|
||||||
u.Manifest = &Manifest{Version: version}
|
u.Manifest = &Manifest{Version: version}
|
||||||
return u.Manifest
|
return u.Manifest
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ping struct {
|
type PingResponse struct {
|
||||||
LastReportDays string `xml:"r,attr,omitempty"`
|
Status string `xml:"status,attr"` // Always "ok".
|
||||||
Status string `xml:"status,attr,omitempty"`
|
}
|
||||||
|
|
||||||
|
type EventResponse struct {
|
||||||
|
Status string `xml:"status,attr"` // Always "ok".
|
||||||
}
|
}
|
||||||
|
|
||||||
type OS struct {
|
type OS struct {
|
||||||
|
|
|
@ -83,10 +83,8 @@ func TestOmahaRequestUpdateCheck(t *testing.T) {
|
||||||
func ExampleNewResponse() {
|
func ExampleNewResponse() {
|
||||||
response := NewResponse()
|
response := NewResponse()
|
||||||
app := response.AddApp("{52F1B9BC-D31A-4D86-9276-CBC256AADF9A}", "ok")
|
app := response.AddApp("{52F1B9BC-D31A-4D86-9276-CBC256AADF9A}", "ok")
|
||||||
p := app.AddPing()
|
app.AddPing()
|
||||||
p.Status = "ok"
|
u := app.AddUpdateCheck(UpdateOK)
|
||||||
u := app.AddUpdateCheck()
|
|
||||||
u.Status = "ok"
|
|
||||||
u.AddURL("http://localhost/updates")
|
u.AddURL("http://localhost/updates")
|
||||||
m := u.AddManifest("9999.0.0")
|
m := u.AddManifest("9999.0.0")
|
||||||
k := m.AddPackage()
|
k := m.AddPackage()
|
||||||
|
|
Loading…
Reference in a new issue