Documentation ¶
Overview ¶
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/master/doc/ServerProtocolV3.md
Index ¶
- Variables
- func LocalArch() string
- func LocalPlatform() string
- type Action
- type AppRequest
- type AppResponse
- type AppStatus
- type DayStart
- type EventRequest
- type EventResponse
- type EventResult
- type EventType
- type Manifest
- type OS
- type OmahaHandler
- type Package
- type PingRequest
- type PingResponse
- type Request
- type Response
- type Server
- type TrivialServer
- type URL
- type Update
- type UpdateRequest
- type UpdateResponse
- type UpdateStatus
- type Updater
- type UpdaterStub
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( PackageHashMismatchError = errors.New("package hash is invalid") PackageSizeMismatchError = errors.New("package size is invalid") )
Functions ¶
func LocalArch ¶
func LocalArch() string
Translate GOARCH to Omaha's choice of names, because no two independent software projects *ever* use the same set of architecture names. ;-)
func LocalPlatform ¶
func LocalPlatform() string
Translate GOOS to Omaha's platform names as best as we can.
Types ¶
type Action ¶
type Action struct { Event string `xml:"event,attr"` // update engine extensions for event="postinstall" DisplayVersion string `xml:"DisplayVersion,attr,omitempty"` SHA256 string `xml:"sha256,attr,omitempty"` NeedsAdmin bool `xml:"needsadmin,attr,omitempty"` IsDeltaPayload bool `xml:"IsDeltaPayload,attr,omitempty"` DisablePayloadBackoff bool `xml:"DisablePayloadBackoff,attr,omitempty"` MaxFailureCountPerURL uint `xml:"MaxFailureCountPerUrl,attr,omitempty"` MetadataSignatureRsa string `xml:"MetadataSignatureRsa,attr,omitempty"` MetadataSize string `xml:"MetadataSize,attr,omitempty"` Deadline string `xml:"deadline,attr,omitempty"` MoreInfo string `xml:"MoreInfo,attr,omitempty"` Prompt bool `xml:"Prompt,attr,omitempty"` }
type AppRequest ¶
type AppRequest struct { Ping *PingRequest `xml:"ping"` UpdateCheck *UpdateRequest `xml:"updatecheck"` Events []*EventRequest `xml:"event" json:",omitempty"` ID string `xml:"appid,attr,omitempty"` Client string `xml:"client,attr,omitempty"` InstallAge string `xml:"installage,attr,omitempty"` Lang string `xml:"lang,attr,omitempty"` NextVersion string `xml:"nextversion,attr,omitempty"` Version string `xml:"version,attr,omitempty"` // update engine extensions Board string `xml:"board,attr,omitempty"` DeltaOK bool `xml:"delta_okay,attr,omitempty"` FromTrack string `xml:"from_track,attr,omitempty"` Track string `xml:"track,attr,omitempty"` // coreos update engine extensions AlephVersion string `xml:"alephversion,attr,omitempty"` BootID string `xml:"bootid,attr,omitempty"` MachineID string `xml:"machineid,attr,omitempty"` OEM string `xml:"oem,attr,omitempty"` OEMVersion string `xml:"oemversion,attr,omitempty"` }
func (*AppRequest) AddEvent ¶
func (a *AppRequest) AddEvent() *EventRequest
func (*AppRequest) AddPing ¶
func (a *AppRequest) AddPing() *PingRequest
func (*AppRequest) AddUpdateCheck ¶
func (a *AppRequest) AddUpdateCheck() *UpdateRequest
type AppResponse ¶
type AppResponse struct { Ping *PingResponse `xml:"ping"` UpdateCheck *UpdateResponse `xml:"updatecheck"` Events []*EventResponse `xml:"event" json:",omitempty"` ID string `xml:"appid,attr,omitempty"` Status AppStatus `xml:"status,attr,omitempty"` }
func (*AppResponse) AddEvent ¶
func (a *AppResponse) AddEvent() *EventResponse
func (*AppResponse) AddPing ¶
func (a *AppResponse) AddPing() *PingResponse
func (*AppResponse) AddUpdateCheck ¶
func (a *AppResponse) AddUpdateCheck(status UpdateStatus) *UpdateResponse
type AppStatus ¶
type AppStatus string
const ( // Standard values AppOK AppStatus = "ok" AppRestricted AppStatus = "restricted" AppUnknownID AppStatus = "error-unknownApplication" AppInvalidID AppStatus = "error-invalidAppId" // Extra error values AppInvalidVersion AppStatus = "error-invalidVersion" AppInternalError AppStatus = "error-internal" )
type EventRequest ¶
type EventRequest struct { Type EventType `xml:"eventtype,attr"` Result EventResult `xml:"eventresult,attr"` ErrorCode int `xml:"errorcode,attr,omitempty"` NextVersion string `xml:"nextversion,attr,omitempty"` PreviousVersion string `xml:"previousversion,attr,omitempty"` }
type EventResponse ¶
type EventResponse struct {
Status string `xml:"status,attr"` // Always "ok".
}
type EventResult ¶
type EventResult int
const ( EventResultError EventResult = 0 EventResultSuccess EventResult = 1 EventResultSuccessReboot EventResult = 2 EventResultSuccessRestartBrowser EventResult = 3 EventResultCancelled EventResult = 4 EventResultErrorInstallerMSI EventResult = 5 EventResultErrorInstallerOther EventResult = 6 EventResultNoUpdate EventResult = 7 EventResultInstallerSystem EventResult = 8 EventResultUpdateDeferred EventResult = 9 EventResultHandoffError EventResult = 10 )
func (EventResult) String ¶
func (e EventResult) String() string
type EventType ¶
type EventType int
const ( EventTypeUnknown EventType = 0 EventTypeDownloadComplete EventType = 1 EventTypeInstallComplete EventType = 2 EventTypeUpdateComplete EventType = 3 EventTypeUninstall EventType = 4 EventTypeDownloadStarted EventType = 5 EventTypeInstallStarted EventType = 6 EventTypeNewApplicationInstallStarted EventType = 9 EventTypeSetupStarted EventType = 10 EventTypeSetupFinished EventType = 11 EventTypeUpdateApplicationStarted EventType = 12 EventTypeUpdateDownloadStarted EventType = 13 EventTypeUpdateDownloadFinished EventType = 14 EventTypeUpdateInstallerStarted EventType = 15 EventTypeSetupUpdateBegin EventType = 16 EventTypeSetupUpdateComplete EventType = 17 EventTypeRegisterProductComplete EventType = 20 EventTypeOEMInstallFirstCheck EventType = 30 EventTypeAppSpecificCommandStarted EventType = 40 EventTypeAppSpecificCommandEnded EventType = 41 EventTypeSetupFailure EventType = 100 EventTypeComServerFailure EventType = 102 EventTypeSetupUpdateFailure EventType = 103 )
type Manifest ¶
type Manifest struct { Packages []*Package `xml:"packages>package"` Actions []*Action `xml:"actions>action"` Version string `xml:"version,attr"` }
func (*Manifest) AddPackage ¶
type OmahaHandler ¶
type OmahaHandler struct {
Updater
}
func (*OmahaHandler) ServeHTTP ¶
func (o *OmahaHandler) ServeHTTP(w http.ResponseWriter, httpReq *http.Request)
type Package ¶
type Package struct { Name string `xml:"name,attr"` SHA1 string `xml:"hash,attr"` SHA256 string `xml:"hash_sha256,attr,omitempty"` Size uint64 `xml:"size,attr"` Required bool `xml:"required,attr"` }
Package represents a single downloadable file.
type PingRequest ¶
type PingResponse ¶
type PingResponse struct {
Status string `xml:"status,attr"` // Always "ok".
}
type Request ¶
type Request struct { XMLName xml.Name `xml:"request" json:"-"` OS *OS `xml:"os"` Apps []*AppRequest `xml:"app"` Protocol string `xml:"protocol,attr"` InstallSource string `xml:"installsource,attr,omitempty"` IsMachine int `xml:"ismachine,attr,omitempty"` RequestID string `xml:"requestid,attr,omitempty"` SessionID string `xml:"sessionid,attr,omitempty"` TestSource string `xml:"testsource,attr,omitempty"` UserID string `xml:"userid,attr,omitempty"` Version string `xml:"version,attr,omitempty"` // update engine extension, duplicates the version attribute. UpdaterVersion string `xml:"updaterversion,attr,omitempty"` }
Request sent by the Omaha client
func NewRequest ¶
func NewRequest() *Request
Example ¶
request := NewRequest() request.Version = "" request.OS = &OS{ Platform: "Chrome OS", Version: "Indy", ServicePack: "ForcedUpdate_x86_64", } app := request.AddApp("{27BD862E-8AE8-4886-A055-F7F1A6460627}", "1.0.0.0") app.AddUpdateCheck() event := app.AddEvent() event.Type = EventTypeDownloadComplete event.Result = EventResultError if raw, err := xml.MarshalIndent(request, "", " "); err != nil { fmt.Println(err) return } else { fmt.Printf("%s%s\n", xml.Header, raw) }
Output: <?xml version="1.0" encoding="UTF-8"?> <request protocol="3.0"> <os platform="Chrome OS" version="Indy" sp="ForcedUpdate_x86_64"></os> <app appid="{27BD862E-8AE8-4886-A055-F7F1A6460627}" version="1.0.0.0"> <updatecheck></updatecheck> <event eventtype="1" eventresult="0"></event> </app> </request>
func ParseRequest ¶
ParseRequest verifies and returns the parsed Request document. The MIME Content-Type header may be provided to sanity check its value; if blank it is assumed to be XML in UTF-8.
func (*Request) AddApp ¶
func (r *Request) AddApp(id, version string) *AppRequest
func (*Request) GetApp ¶
func (r *Request) GetApp(id string) *AppRequest
type Response ¶
type Response struct { XMLName xml.Name `xml:"response" json:"-"` DayStart DayStart `xml:"daystart"` Apps []*AppResponse `xml:"app"` Protocol string `xml:"protocol,attr"` Server string `xml:"server,attr"` }
Response sent by the Omaha server
func NewResponse ¶
func NewResponse() *Response
Example ¶
response := NewResponse() app := response.AddApp("{52F1B9BC-D31A-4D86-9276-CBC256AADF9A}", "ok") app.AddPing() u := app.AddUpdateCheck(UpdateOK) u.AddURL("http://localhost/updates") m := u.AddManifest("9999.0.0") k := m.AddPackage() k.SHA1 = "+LXvjiaPkeYDLHoNKlf9qbJwvnk=" k.Name = "update.gz" k.Size = 67546213 k.Required = true a := m.AddAction("postinstall") a.DisplayVersion = "9999.0.0" a.SHA256 = "0VAlQW3RE99SGtSB5R4m08antAHO8XDoBMKDyxQT/Mg=" a.NeedsAdmin = false a.IsDeltaPayload = true a.DisablePayloadBackoff = true if raw, err := xml.MarshalIndent(response, "", " "); err != nil { fmt.Println(err) return } else { fmt.Printf("%s%s\n", xml.Header, raw) }
Output: <?xml version="1.0" encoding="UTF-8"?> <response protocol="3.0" server="go-omaha"> <daystart elapsed_seconds="0"></daystart> <app appid="{52F1B9BC-D31A-4D86-9276-CBC256AADF9A}" status="ok"> <ping status="ok"></ping> <updatecheck status="ok"> <urls> <url codebase="http://localhost/updates"></url> </urls> <manifest version="9999.0.0"> <packages> <package name="update.gz" hash="+LXvjiaPkeYDLHoNKlf9qbJwvnk=" size="67546213" required="true"></package> </packages> <actions> <action event="postinstall" DisplayVersion="9999.0.0" sha256="0VAlQW3RE99SGtSB5R4m08antAHO8XDoBMKDyxQT/Mg=" IsDeltaPayload="true" DisablePayloadBackoff="true"></action> </actions> </manifest> </updatecheck> </app> </response>
func ParseResponse ¶
ParseResponse verifies and returns the parsed Response document. The MIME Content-Type header may be provided to sanity check its value; if blank it is assumed to be XML in UTF-8.
func (*Response) GetApp ¶
func (r *Response) GetApp(id string) *AppResponse
type TrivialServer ¶
type TrivialServer struct { *Server // contains filtered or unexported fields }
TrivialServer is an extremely basic Omaha server that ignores all incoming metadata, always responding with the same update response. The update is constructed by calling AddPackage one or more times.
func NewTrivialServer ¶
func NewTrivialServer(addr string) (*TrivialServer, error)
func (*TrivialServer) AddPackage ¶
func (ts *TrivialServer) AddPackage(file, name string) error
AddPackage adds a new file to the update response. file is the local filesystem path, name is the final URL component.
func (*TrivialServer) SetVersion ¶
func (ts *TrivialServer) SetVersion(version string)
SetVersion sets the manifest's version with the provided one.
type Update ¶
type Update struct { XMLName xml.Name `xml:"update" json:"-"` ID string `xml:"appid,attr"` PreviousVersion string `xml:"previousversion,attr,omitempty"` URL URL `xml:"urls>url"` Manifest // The delta_okay request attribute is an update_engine extension. RespectDeltaOK bool `xml:"respect_delta_okay,attr,omitempty"` }
Update is a manifest for a single omaha update response. It extends the standard Manifest protocol element with the application id and previous version which are used to match against the update request. A blank previous version indicates this update can be applied to any existing install. The application id may not be blank.
type UpdateRequest ¶
type UpdateRequest struct {
TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
}
type UpdateResponse ¶
type UpdateResponse struct { URLs []*URL `xml:"urls>url" json:",omitempty"` Manifest *Manifest `xml:"manifest"` Status UpdateStatus `xml:"status,attr,omitempty"` }
func (*UpdateResponse) AddManifest ¶
func (u *UpdateResponse) AddManifest(version string) *Manifest
func (*UpdateResponse) AddURL ¶
func (u *UpdateResponse) AddURL(codebase string) *URL
type UpdateStatus ¶
type UpdateStatus string
const ( NoUpdate UpdateStatus = "noupdate" UpdateOK UpdateStatus = "ok" UpdateOSNotSupported UpdateStatus = "error-osnotsupported" UpdateUnsupportedProtocol UpdateStatus = "error-unsupportedProtocol" UpdatePluginRestrictedHost UpdateStatus = "error-pluginRestrictedHost" UpdateHashError UpdateStatus = "error-hash" UpdateInternalError UpdateStatus = "error-internal" )
func (UpdateStatus) Error ¶
func (u UpdateStatus) Error() string
Make UpdateStatus easy to use as an error
type Updater ¶
type Updater interface { CheckApp(req *Request, app *AppRequest) error CheckUpdate(req *Request, app *AppRequest) (*Update, error) Event(req *Request, app *AppRequest, event *EventRequest) Ping(req *Request, app *AppRequest) }
Updater provides a common interface for any backend that can respond to update requests made to an Omaha server.
type UpdaterStub ¶
type UpdaterStub struct{}
func (UpdaterStub) CheckApp ¶
func (u UpdaterStub) CheckApp(req *Request, app *AppRequest) error
func (UpdaterStub) CheckUpdate ¶
func (u UpdaterStub) CheckUpdate(req *Request, app *AppRequest) (*Update, error)
func (UpdaterStub) Event ¶
func (u UpdaterStub) Event(req *Request, app *AppRequest, event *EventRequest)
func (UpdaterStub) Ping ¶
func (u UpdaterStub) Ping(req *Request, app *AppRequest)