omaha

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2017 License: Apache-2.0 Imports: 16 Imported by: 0

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/wiki/ServerProtocol.md

Index

Examples

Constants

This section is empty.

Variables

View Source
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"`
	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"`
	Board     string `xml:"board,attr,omitempty"`
	DeltaOK   bool   `xml:"delta_okay,attr,omitempty"`

	// coreos update engine extensions
	BootId       string `xml:"bootid,attr,omitempty"`
	MachineID    string `xml:"machineid,attr,omitempty"`
	OEM          string `xml:"oem,attr,omitempty"`
	OEMVersion   string `xml:"oemversion,attr,omitempty"`
	AlephVersion string `xml:"alephversion,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"
)

func (AppStatus) Error

func (a AppStatus) Error() string

Make AppStatus easy to use as an error

type DayStart

type DayStart struct {
	ElapsedSeconds string `xml:"elapsed_seconds,attr"`
}

type Event

type Event struct {
	Type            EventType   `xml:"eventtype,attr"`
	Result          EventResult `xml:"eventresult,attr"`
	PreviousVersion string      `xml:"previousversion,attr,omitempty"`
	ErrorCode       string      `xml:"errorcode,attr,omitempty"`
	Status          string      `xml:"status,attr,omitempty"`
}

type EventRequest

type EventRequest struct {
	Type            EventType   `xml:"eventtype,attr"`
	Result          EventResult `xml:"eventresult,attr"`
	NextVersion     string      `xml:"nextversion,attr,omitempty"`
	PreviousVersion string      `xml:"previousversion,attr,omitempty"`
	ErrorCode       string      `xml:"errorcode,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
)

func (EventType) String

func (e EventType) String() string

type Manifest

type Manifest struct {
	Packages []*Package `xml:"packages>package"`
	Actions  []*Action  `xml:"actions>action"`
	Version  string     `xml:"version,attr"`
}

func (*Manifest) AddAction

func (m *Manifest) AddAction(event string) *Action

func (*Manifest) AddPackage

func (m *Manifest) AddPackage() *Package

func (*Manifest) AddPackageFromPath

func (m *Manifest) AddPackageFromPath(path string) (*Package, error)

type OS

type OS struct {
	Platform    string `xml:"platform,attr,omitempty"`
	Version     string `xml:"version,attr,omitempty"`
	ServicePack string `xml:"sp,attr,omitempty"`
	Arch        string `xml:"arch,attr,omitempty"`
}

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:"sha256,attr,omitempty"`
	Size     uint64 `xml:"size,attr"`
	Required bool   `xml:"required,attr"`
}

Package represents a single downloadable file. The Sha256 attribute is not a standard part of the Omaha protocol which only uses Sha1.

func (*Package) FromPath

func (p *Package) FromPath(name string) error

func (*Package) FromReader

func (p *Package) FromReader(r io.Reader) error

func (*Package) Verify

func (p *Package) Verify(dir string) error

func (*Package) VerifyReader

func (p *Package) VerifyReader(r io.Reader) error

type PingRequest

type PingRequest struct {
	Active               int `xml:"active,attr,omitempty"`
	LastActiveReportDays int `xml:"a,attr,omitempty"`
	LastReportDays       int `xml:"r,attr,omitempty"`
}

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"`
	Version       string        `xml:"version,attr,omitempty"`
	IsMachine     string        `xml:"ismachine,attr,omitempty"`
	RequestId     string        `xml:"requestid,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"`

	// 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 (*Request) AddApp

func (r *Request) AddApp(id, version 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="mantle">
 <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 (*Response) AddApp

func (r *Response) AddApp(id string, status AppStatus) *AppResponse

type Server

type Server struct {
	Updater

	Mux *http.ServeMux
	// contains filtered or unexported fields
}

func NewServer

func NewServer(addr string, updater Updater) (*Server, error)

func (*Server) Addr

func (s *Server) Addr() net.Addr

func (*Server) Destroy

func (s *Server) Destroy() error

func (*Server) Serve

func (s *Server) Serve() error

type TrivialServer added in v0.2.0

type TrivialServer struct {
	*Server
	// contains filtered or unexported fields
}

func NewTrivialServer added in v0.2.0

func NewTrivialServer(addr string) (*TrivialServer, error)

func (*TrivialServer) SetPackage added in v0.2.0

func (ts *TrivialServer) SetPackage(path string) error

type URL

type URL struct {
	CodeBase string `xml:"codebase,attr"`
}

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.

func (*Update) URLs

func (u *Update) URLs(prefixes []string) []*URL

The URL attribute in Update is currently assumed to be a relative path which may be found on multiple mirrors. A server using this is expected to know the mirror prefix(s) it can give the client.

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)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL