1*9712c20fSFrederick Mayle# Introduction 2*9712c20fSFrederick Mayle 3*9712c20fSFrederick MayleThe `sym_upload` tool is able to operate in `sym-upload-v2` protocol mode, in 4*9712c20fSFrederick Mayleaddition to the legacy protocol (which will be referred to as `sym-upload-v1` 5*9712c20fSFrederick Maylefor the rest of this document). For now `sym-upload-v2` is HTTP/REST-based but 6*9712c20fSFrederick Mayleit could be extended to operate over gRPC instead, in the future. 7*9712c20fSFrederick Mayle 8*9712c20fSFrederick Mayle# Table of Contents 9*9712c20fSFrederick Mayle* [Why](#why) 10*9712c20fSFrederick Mayle* [How](#how) 11*9712c20fSFrederick Mayle * [Uploading](#uploading) 12*9712c20fSFrederick Mayle * [Uploading with `sym_upload`](#uploading-with-sym_upload) 13*9712c20fSFrederick Mayle * [Uploading with curl](#uploading-with-curl) 14*9712c20fSFrederick Mayle * [Serving the `sym-upload-v2` protocol](#serving-the-sym-upload-v2-protocol) 15*9712c20fSFrederick Mayle * [Authenticate using `key`](#authenticate-using-key) 16*9712c20fSFrederick Mayle * [Symbol `checkStatus`](#symbol-checkstatus) 17*9712c20fSFrederick Mayle * [Upload `create`](#upload-create) 18*9712c20fSFrederick Mayle * [Uploading the symbol file](#uploading-the-symbol-file) 19*9712c20fSFrederick Mayle * [Upload complete](#upload-complete) 20*9712c20fSFrederick Mayle 21*9712c20fSFrederick Mayle 22*9712c20fSFrederick Mayle# Why 23*9712c20fSFrederick Mayle 24*9712c20fSFrederick MayleUsing `sym_upload` in `sym-upload-v2` protocol mode has the following features 25*9712c20fSFrederick Maylebeyond `sym-upload-v1`: 26*9712c20fSFrederick Mayle * Authentication via `key` (arbitrary secret). 27*9712c20fSFrederick Mayle * Symbol identifier (product of `debug_file` and `debug_id`, as recorded in 28*9712c20fSFrederick Mayleoutput from `dump_syms`) can be checked against existing symbol information on 29*9712c20fSFrederick Mayleserver. If it's present, then the upload is skipped entirely. 30*9712c20fSFrederick Mayle 31*9712c20fSFrederick Mayle# How 32*9712c20fSFrederick Mayle 33*9712c20fSFrederick Mayle## Uploading 34*9712c20fSFrederick Mayle 35*9712c20fSFrederick Mayle### Uploading with `sym_upload` 36*9712c20fSFrederick Mayle 37*9712c20fSFrederick MayleUploading in `sym-upload-v2` protocol mode is easy. Invoke `sym_upload` like 38*9712c20fSFrederick Mayle``` 39*9712c20fSFrederick Mayle$ ./sym_upload -p sym-upload-v2 [-k <API-key>] <symbol-file> <API-URL> 40*9712c20fSFrederick Mayle``` 41*9712c20fSFrederick Mayle 42*9712c20fSFrederick MayleWhere `symbol-file` is a symbol file created by `dump_syms`, `API-URL` is the 43*9712c20fSFrederick MayleURL of your `sym-upload-v2` API service (see next section for details), and 44*9712c20fSFrederick Mayle`API-key` is a secret known to your uploader and server. 45*9712c20fSFrederick Mayle 46*9712c20fSFrederick MayleFor more options see `sym_upload --help`. 47*9712c20fSFrederick Mayle 48*9712c20fSFrederick Mayle### Uploading with curl 49*9712c20fSFrederick Mayle 50*9712c20fSFrederick MayleAs an example, if: 51*9712c20fSFrederick Mayle * Your API's URL was "https://sym-upload-api". 52*9712c20fSFrederick Mayle * Your service has assigned you `key` "myfancysecret123". 53*9712c20fSFrederick Mayle * You wanted to upload the symbol file at "path/to/file_name", with 54*9712c20fSFrederick Mayle`debug_file` being "file_name" and `debug_id` being 55*9712c20fSFrederick Mayle"123123123123123123123123123". Normally you would read these values from 56*9712c20fSFrederick Mayle"path/to/file_name", which in turn was generated by `dump_syms`. 57*9712c20fSFrederick Mayle 58*9712c20fSFrederick MayleThen you might run: 59*9712c20fSFrederick Mayle``` 60*9712c20fSFrederick Mayle$ curl https://sym-upload-api/symbols/file_name/123123123123123123123123123:checkStatus?key=myfancysecret123 61*9712c20fSFrederick Mayle``` 62*9712c20fSFrederick Mayle 63*9712c20fSFrederick MayleAnd, upon seeing that this `debug_file`/`debug_id` combo is missing from symbol 64*9712c20fSFrederick Maylestorage then you could run: 65*9712c20fSFrederick Mayle``` 66*9712c20fSFrederick Mayle$ curl --request POST https://sym-upload-api/uploads:create?key=myfancysecret123 67*9712c20fSFrederick Mayle``` 68*9712c20fSFrederick Mayle 69*9712c20fSFrederick MayleWhich returns `upload_url` "https://upload-server/42?creds=shhhhh" and 70*9712c20fSFrederick Mayle`upload_key` "42". Next you upload the file directly like: 71*9712c20fSFrederick Mayle``` 72*9712c20fSFrederick Mayle$ curl -T path/to/file_name "https://upload-server/42?creds=shhhhh" 73*9712c20fSFrederick Mayle``` 74*9712c20fSFrederick Mayle 75*9712c20fSFrederick MayleOnce the HTTP PUT is complete, run: 76*9712c20fSFrederick Mayle``` 77*9712c20fSFrederick Mayle$ curl --header "Content-Type: application/json" \ 78*9712c20fSFrederick Mayle --request POST \ 79*9712c20fSFrederick Mayle --data '{symbol_id:{"debugFile":"file_name",'\ 80*9712c20fSFrederick Mayle '"debugId":"123123123123123123123123123"}}' \ 81*9712c20fSFrederick Mayle https://sym-upload-api/uploads/42:complete?key=myfancysecret123 82*9712c20fSFrederick Mayle``` 83*9712c20fSFrederick Mayle 84*9712c20fSFrederick Mayle### Serving the `sym-upload-v2` Protocol 85*9712c20fSFrederick Mayle 86*9712c20fSFrederick MayleThe protocol is currently defined only in HTTP/REST. There are three necessary 87*9712c20fSFrederick MayleREST operations to implement in your service: 88*9712c20fSFrederick Mayle* `/symbols/<debug_file>/<debug_id>:checkStatus?key=<key>` 89*9712c20fSFrederick Mayle* `/uploads:create?key=<key>` 90*9712c20fSFrederick Mayle* `/uploads/<upload_key>:complete?key=<key>` 91*9712c20fSFrederick Mayle 92*9712c20fSFrederick Mayle#### Authenticate Using `key` 93*9712c20fSFrederick Mayle 94*9712c20fSFrederick MayleThe query string arg `key` contains some secret that both the uploader and 95*9712c20fSFrederick Mayleserver understand. It is up to the service implementer to decide on what 96*9712c20fSFrederick Mayleconstitutes a valid `key`, how the uploader acquires one, and how to handle 97*9712c20fSFrederick Maylerequests made with invalid ones. 98*9712c20fSFrederick Mayle 99*9712c20fSFrederick Mayle#### Symbol `checkStatus` 100*9712c20fSFrederick Mayle 101*9712c20fSFrederick Mayle``` 102*9712c20fSFrederick Mayle/symbols/<debug_file>/<debug_id>:checkStatus?key=<key> 103*9712c20fSFrederick Mayle``` 104*9712c20fSFrederick Mayle 105*9712c20fSFrederick MayleThis operation expects an empty (or no) JSON payload in the request. 106*9712c20fSFrederick Mayle 107*9712c20fSFrederick MayleThis operation should return the status of the symbol file uniquely identified 108*9712c20fSFrederick Mayleby the given `debug_file` and `debug_id`. JSON schema: 109*9712c20fSFrederick Mayle``` 110*9712c20fSFrederick Mayle{ 111*9712c20fSFrederick Mayle "type": object", 112*9712c20fSFrederick Mayle "properties": { 113*9712c20fSFrederick Mayle "status": { 114*9712c20fSFrederick Mayle "type": "string", 115*9712c20fSFrederick Mayle "enum": ["STATUS_UNSPECIFIED", "MISING", "FOUND"], 116*9712c20fSFrederick Mayle "required": true 117*9712c20fSFrederick Mayle } 118*9712c20fSFrederick Mayle } 119*9712c20fSFrederick Mayle} 120*9712c20fSFrederick Mayle``` 121*9712c20fSFrederick Mayle 122*9712c20fSFrederick MayleWhere `MISSING` denotes that the symbol file does not exist on the server and 123*9712c20fSFrederick Mayle`FOUND` denotes that the symbol file exists on the server. 124*9712c20fSFrederick Mayle 125*9712c20fSFrederick Mayle#### Upload `create` 126*9712c20fSFrederick Mayle 127*9712c20fSFrederick Mayle``` 128*9712c20fSFrederick Mayle/uploads:create?key=<key> 129*9712c20fSFrederick Mayle``` 130*9712c20fSFrederick Mayle 131*9712c20fSFrederick MayleThis operation expects an empty (or no) JSON payload in the request. 132*9712c20fSFrederick Mayle 133*9712c20fSFrederick MayleThis operation should return a URL that uploader can HTTP PUT their symbol file 134*9712c20fSFrederick Mayleto, along with an "upload key" that can be used to notify the service once the 135*9712c20fSFrederick Maylefile upload is completed. JSON schema: 136*9712c20fSFrederick Mayle``` 137*9712c20fSFrederick Mayle{ 138*9712c20fSFrederick Mayle "type": "object", 139*9712c20fSFrederick Mayle "properties": { 140*9712c20fSFrederick Mayle "upload_url": { 141*9712c20fSFrederick Mayle "type: "string", 142*9712c20fSFrederick Mayle "required": true 143*9712c20fSFrederick Mayle }, 144*9712c20fSFrederick Mayle "upload_key": { 145*9712c20fSFrederick Mayle "type": "string", 146*9712c20fSFrederick Mayle "required": true 147*9712c20fSFrederick Mayle } 148*9712c20fSFrederick Mayle } 149*9712c20fSFrederick Mayle} 150*9712c20fSFrederick Mayle``` 151*9712c20fSFrederick Mayle 152*9712c20fSFrederick MayleSince this REST API operation can be authenticated via the `key` query string 153*9712c20fSFrederick Maylearg, the service can return a URL that encodes permission delegation to the 154*9712c20fSFrederick Mayleupload endpoint resource and thereby constrain the ability to upload to those 155*9712c20fSFrederick Maylewith valid `key`s. 156*9712c20fSFrederick Mayle 157*9712c20fSFrederick Mayle#### Uploading the Symbol File 158*9712c20fSFrederick Mayle 159*9712c20fSFrederick MayleNote that the actual symbol upload step is _not_ part of the REST API. The 160*9712c20fSFrederick Mayleupload URL obtained in the above operation is meant to be used as the endpoint 161*9712c20fSFrederick Maylefor a normal HTTP PUT request for the contents of the symbol file. Once that 162*9712c20fSFrederick MayleHTTP PUT request is completed use the upload `complete` operation. 163*9712c20fSFrederick Mayle 164*9712c20fSFrederick Mayle#### Upload `complete` 165*9712c20fSFrederick Mayle 166*9712c20fSFrederick Mayle``` 167*9712c20fSFrederick Mayle/uploads/<upload_key>:complete?key=<key> 168*9712c20fSFrederick Mayle``` 169*9712c20fSFrederick Mayle 170*9712c20fSFrederick MayleThis operation expects a JSON payload in the HTTP request body with the 171*9712c20fSFrederick Maylefollowing schema: 172*9712c20fSFrederick Mayle``` 173*9712c20fSFrederick Mayle{ 174*9712c20fSFrederick Mayle "type": "object", 175*9712c20fSFrederick Mayle "properties": { 176*9712c20fSFrederick Mayle "symbol_id": { 177*9712c20fSFrederick Mayle "type": "object", 178*9712c20fSFrederick Mayle "properties": { 179*9712c20fSFrederick Mayle "debug_file": { 180*9712c20fSFrederick Mayle "type": "string", 181*9712c20fSFrederick Mayle "required": true 182*9712c20fSFrederick Mayle }, 183*9712c20fSFrederick Mayle "debug_id": { 184*9712c20fSFrederick Mayle "type": "string", 185*9712c20fSFrederick Mayle "required": true 186*9712c20fSFrederick Mayle } 187*9712c20fSFrederick Mayle } 188*9712c20fSFrederick Mayle } 189*9712c20fSFrederick Mayle } 190*9712c20fSFrederick Mayle} 191*9712c20fSFrederick Mayle``` 192*9712c20fSFrederick Mayle 193*9712c20fSFrederick MayleThis operation should cause the symbol storage back-end (however implemented) 194*9712c20fSFrederick Mayleto consume the symbol file identified by `upload_key`. It is up to the service 195*9712c20fSFrederick Mayleimplementation to decide how uploads are assigned `upload_key`s and how to 196*9712c20fSFrederick Mayleretrieve a completed upload by its `upload_key`. If the symbol file cannot be 197*9712c20fSFrederick Maylefound, is malformed, or the operation cannot be completed for any other reason 198*9712c20fSFrederick Maylethen an HTTP error will be returned. JSON schema of non-error responses: 199*9712c20fSFrederick Mayle``` 200*9712c20fSFrederick Mayle{ 201*9712c20fSFrederick Mayle "type": "object", 202*9712c20fSFrederick Mayle "properties": { 203*9712c20fSFrederick Mayle "result": { 204*9712c20fSFrederick Mayle "type": string, 205*9712c20fSFrederick Mayle "enum": ["RESULT_UNSPECIFIED", "OK", "DUPLICATE_DATA"], 206*9712c20fSFrederick Mayle "required": true 207*9712c20fSFrederick Mayle } 208*9712c20fSFrederick Mayle } 209*9712c20fSFrederick Mayle} 210*9712c20fSFrederick Mayle``` 211*9712c20fSFrederick Mayle 212*9712c20fSFrederick MayleWhere `OK` denotes that the symbol storage was updated with the new symbol file 213*9712c20fSFrederick Mayleand `DUPLICATE_DATA` denotes that the symbol file data was identical to data 214*9712c20fSFrederick Maylealready in symbol storage and therefore nothing changed. 215