2015-07-23 05:31:47 +00:00
|
|
|
// Copyright 2013-2015 CoreOS, Inc.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
2013-03-27 23:58:22 +00:00
|
|
|
|
2015-07-23 05:31:47 +00:00
|
|
|
// Google's Omaha application update protocol, version 3.
|
|
|
|
//
|
|
|
|
// Omaha is a poll based protocol using XML. Requests are made by clients to
|
|
|
|
// check for updates or report events of an update process. Responses are given
|
|
|
|
// by the server to provide update information, if any, or to simply
|
|
|
|
// acknowledge the receipt of event status.
|
|
|
|
//
|
|
|
|
// https://github.com/google/omaha/blob/wiki/ServerProtocol.md
|
2013-03-27 23:58:22 +00:00
|
|
|
package omaha
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
)
|
2013-03-27 23:58:22 +00:00
|
|
|
|
|
|
|
type Request struct {
|
2013-06-25 23:39:01 +00:00
|
|
|
XMLName xml.Name `xml:"request" datastore:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
Os Os `xml:"os"`
|
|
|
|
Apps []*App `xml:"app"`
|
|
|
|
Protocol string `xml:"protocol,attr"`
|
|
|
|
Version string `xml:"version,attr,omitempty"`
|
|
|
|
IsMachine string `xml:"ismachine,attr,omitempty"`
|
|
|
|
SessionId string `xml:"sessionid,attr,omitempty"`
|
|
|
|
UserId string `xml:"userid,attr,omitempty"`
|
|
|
|
InstallSource string `xml:"installsource,attr,omitempty"`
|
|
|
|
TestSource string `xml:"testsource,attr,omitempty"`
|
|
|
|
RequestId string `xml:"requestid,attr,omitempty"`
|
|
|
|
UpdaterVersion string `xml:"updaterversion,attr,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRequest(version string, platform string, sp string, arch string) *Request {
|
2013-03-27 23:58:22 +00:00
|
|
|
r := new(Request)
|
|
|
|
r.Protocol = "3.0"
|
2013-04-01 16:59:32 +00:00
|
|
|
r.Os = Os{Version: version, Platform: platform, Sp: sp, Arch: arch}
|
2013-03-27 23:58:22 +00:00
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
func (r *Request) AddApp(id string, version string) *App {
|
|
|
|
a := NewApp(id)
|
|
|
|
a.Version = version
|
|
|
|
r.Apps = append(r.Apps, a)
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
type Response struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"response" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
DayStart DayStart `xml:"daystart"`
|
|
|
|
Apps []*App `xml:"app"`
|
|
|
|
Protocol string `xml:"protocol,attr"`
|
|
|
|
Server string `xml:"server,attr"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewResponse(server string) *Response {
|
|
|
|
r := &Response{Server: server, Protocol: "3.0"}
|
|
|
|
r.DayStart.ElapsedSeconds = "0"
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
type DayStart struct {
|
|
|
|
ElapsedSeconds string `xml:"elapsed_seconds,attr"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Response) AddApp(id string) *App {
|
|
|
|
a := NewApp(id)
|
|
|
|
r.Apps = append(r.Apps, a)
|
|
|
|
return a
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type App struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"app" datastore"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
Ping *Ping `xml:"ping"`
|
2013-03-27 23:58:22 +00:00
|
|
|
UpdateCheck *UpdateCheck `xml:"updatecheck"`
|
2013-07-01 20:17:08 +00:00
|
|
|
Events []*Event `xml:"event" json:",omitempty"`
|
2013-04-01 16:53:53 +00:00
|
|
|
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"`
|
|
|
|
Status string `xml:"status,attr,omitempty"`
|
2013-07-02 16:47:19 +00:00
|
|
|
|
|
|
|
// update engine extensions
|
2013-09-03 23:20:46 +00:00
|
|
|
Track string `xml:"track,attr,omitempty"`
|
|
|
|
FromTrack string `xml:"from_track,attr,omitempty"`
|
2013-07-09 18:48:57 +00:00
|
|
|
|
|
|
|
// coreos update engine extensions
|
2014-03-17 21:29:04 +00:00
|
|
|
BootId string `xml:"bootid,attr,omitempty"`
|
|
|
|
MachineID string `xml:"machineid,attr,omitempty"`
|
|
|
|
OEM string `xml:"oem,attr,omitempty"`
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
func NewApp(id string) *App {
|
|
|
|
a := &App{Id: id}
|
|
|
|
return a
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
func (a *App) AddUpdateCheck() *UpdateCheck {
|
2013-03-27 23:58:22 +00:00
|
|
|
a.UpdateCheck = new(UpdateCheck)
|
2013-04-01 16:53:53 +00:00
|
|
|
return a.UpdateCheck
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *App) AddPing() *Ping {
|
|
|
|
a.Ping = new(Ping)
|
|
|
|
return a.Ping
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:08:19 +00:00
|
|
|
func (a *App) AddEvent() *Event {
|
|
|
|
event := new(Event)
|
|
|
|
a.Events = append(a.Events, event)
|
|
|
|
return event
|
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
type UpdateCheck struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"updatecheck" datastore:"-" json:"-"`
|
2013-06-25 15:08:19 +00:00
|
|
|
Urls *Urls `xml:"urls"`
|
|
|
|
Manifest *Manifest `xml:"manifest"`
|
|
|
|
TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
|
|
|
|
Status string `xml:"status,attr,omitempty"`
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
2013-04-14 04:35:44 +00:00
|
|
|
func (u *UpdateCheck) AddUrl(codebase string) *Url {
|
|
|
|
if u.Urls == nil {
|
|
|
|
u.Urls = new(Urls)
|
|
|
|
}
|
|
|
|
url := new(Url)
|
|
|
|
url.CodeBase = codebase
|
|
|
|
u.Urls.Urls = append(u.Urls.Urls, *url)
|
|
|
|
return url
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *UpdateCheck) AddManifest(version string) *Manifest {
|
|
|
|
u.Manifest = &Manifest{Version: version}
|
|
|
|
return u.Manifest
|
|
|
|
}
|
|
|
|
|
2013-03-27 23:58:22 +00:00
|
|
|
type Ping struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"ping" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
LastReportDays string `xml:"r,attr,omitempty"`
|
|
|
|
Status string `xml:"status,attr,omitempty"`
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Os struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"os" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
Platform string `xml:"platform,attr,omitempty"`
|
|
|
|
Version string `xml:"version,attr,omitempty"`
|
|
|
|
Sp string `xml:"sp,attr,omitempty"`
|
|
|
|
Arch string `xml:"arch,attr,omitempty"`
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewOs(platform string, version string, sp string, arch string) *Os {
|
2013-04-01 16:59:32 +00:00
|
|
|
o := &Os{Version: version, Platform: platform, Sp: sp, Arch: arch}
|
2013-03-27 23:58:22 +00:00
|
|
|
return o
|
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
type Event struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"event" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
Type string `xml:"eventtype,attr,omitempty"`
|
|
|
|
Result string `xml:"eventresult,attr,omitempty"`
|
|
|
|
PreviousVersion string `xml:"previousversion,attr,omitempty"`
|
2014-05-23 18:26:29 +00:00
|
|
|
ErrorCode string `xml:"errorcode,attr,omitempty"`
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
type Urls struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"urls" datastore:"-" json:"-"`
|
2013-07-01 20:17:08 +00:00
|
|
|
Urls []Url `xml:"url" json:",omitempty"`
|
2013-04-01 16:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Url struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"url" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
CodeBase string `xml:"codebase,attr"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Manifest struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"manifest" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
Packages Packages `xml:"packages"`
|
|
|
|
Actions Actions `xml:"actions"`
|
|
|
|
Version string `xml:"version,attr"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Packages struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"packages" datastore:"-" json:"-"`
|
2013-07-01 20:17:08 +00:00
|
|
|
Packages []Package `xml:"package" json:",omitempty"`
|
2013-04-01 16:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Package struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"package" datastore:"-" json:"-"`
|
2013-04-01 16:53:53 +00:00
|
|
|
Hash string `xml:"hash,attr"`
|
|
|
|
Name string `xml:"name,attr"`
|
|
|
|
Size string `xml:"size,attr"`
|
|
|
|
Required bool `xml:"required,attr"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Manifest) AddPackage(hash string, name string, size string, required bool) *Package {
|
|
|
|
p := &Package{Hash: hash, Name: name, Size: size, Required: required}
|
|
|
|
m.Packages.Packages = append(m.Packages.Packages, *p)
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
type Actions struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"actions" datastore:"-" json:"-"`
|
2013-07-01 20:17:08 +00:00
|
|
|
Actions []*Action `xml:"action" json:",omitempty"`
|
2013-04-01 16:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Action struct {
|
2013-06-29 05:48:55 +00:00
|
|
|
XMLName xml.Name `xml:"action" datastore:"-" json:"-"`
|
2013-06-26 22:53:31 +00:00
|
|
|
Event string `xml:"event,attr"`
|
2013-06-26 17:24:43 +00:00
|
|
|
|
|
|
|
// Extensions added by update_engine
|
2013-06-26 22:53:31 +00:00
|
|
|
ChromeOSVersion string `xml:"ChromeOSVersion,attr"`
|
|
|
|
Sha256 string `xml:"sha256,attr"`
|
|
|
|
NeedsAdmin bool `xml:"needsadmin,attr"`
|
|
|
|
IsDelta bool `xml:"IsDelta,attr"`
|
|
|
|
DisablePayloadBackoff bool `xml:"DisablePayloadBackoff,attr,omitempty"`
|
|
|
|
MetadataSignatureRsa string `xml:"MetadataSignatureRsa,attr,omitempty"`
|
|
|
|
MetadataSize string `xml:"MetadataSize,attr,omitempty"`
|
|
|
|
Deadline string `xml:"deadline,attr,omitempty"`
|
2013-04-01 16:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Manifest) AddAction(event string) *Action {
|
|
|
|
a := &Action{Event: event}
|
2013-04-11 19:07:55 +00:00
|
|
|
m.Actions.Actions = append(m.Actions.Actions, a)
|
2013-04-01 16:53:53 +00:00
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
var EventTypes = map[int]string{
|
|
|
|
0: "unknown",
|
|
|
|
1: "download complete",
|
|
|
|
2: "install complete",
|
|
|
|
3: "update complete",
|
|
|
|
4: "uninstall",
|
|
|
|
5: "download started",
|
|
|
|
6: "install started",
|
|
|
|
9: "new application install started",
|
|
|
|
10: "setup started",
|
|
|
|
11: "setup finished",
|
|
|
|
12: "update application started",
|
|
|
|
13: "update download started",
|
|
|
|
14: "update download finished",
|
|
|
|
15: "update installer started",
|
|
|
|
16: "setup update begin",
|
|
|
|
17: "setup update complete",
|
|
|
|
20: "register product complete",
|
|
|
|
30: "OEM install first check",
|
|
|
|
40: "app-specific command started",
|
|
|
|
41: "app-specific command ended",
|
2013-03-27 23:58:22 +00:00
|
|
|
100: "setup failure",
|
|
|
|
102: "COM server failure",
|
|
|
|
103: "setup update failure",
|
2014-05-14 23:16:44 +00:00
|
|
|
800: "ping",
|
2013-03-27 23:58:22 +00:00
|
|
|
}
|
|
|
|
|
2013-04-01 16:53:53 +00:00
|
|
|
var EventResults = map[int]string{
|
|
|
|
0: "error",
|
|
|
|
1: "success",
|
|
|
|
2: "success reboot",
|
|
|
|
3: "success restart browser",
|
|
|
|
4: "cancelled",
|
|
|
|
5: "error installer MSI",
|
|
|
|
6: "error installer other",
|
|
|
|
7: "noupdate",
|
|
|
|
8: "error installer system",
|
|
|
|
9: "update deferred",
|
2013-03-27 23:58:22 +00:00
|
|
|
10: "handoff error",
|
|
|
|
}
|