Merge lp:~pedronis/ubuntu-push/acceptcli-enhancements into lp:ubuntu-push/automatic

Proposed by Samuele Pedroni
Status: Merged
Approved by: Samuele Pedroni
Approved revision: 406
Merged at revision: 405
Proposed branch: lp:~pedronis/ubuntu-push/acceptcli-enhancements
Merge into: lp:ubuntu-push/automatic
Diff against target: 249 lines (+105/-27)
4 files modified
server/acceptance/acceptanceclient.go (+6/-1)
server/acceptance/cmd/acceptanceclient.go (+1/-1)
server/acceptance/kit/api.go (+41/-7)
server/acceptance/kit/cliloop.go (+57/-18)
To merge this branch: bzr merge lp:~pedronis/ubuntu-push/acceptcli-enhancements
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Review via email: mp+261111@code.launchpad.net

Commit message

* teach acceptance/kit.CliLoop to ask for hosts based on the deviceid hash to respect conistent hashing, explicitly specifying -addr still skips this,

* added some knobs to the acceptance.ClietnSession config

Description of the change

* teach acceptance/kit.CliLoop to ask for hosts based on the deviceid hash to respect conistent hashing, explicitly specifying -addr still skips this,

* added some knobs to the acceptance.ClietnSession config

To post a comment you must log in.
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'server/acceptance/acceptanceclient.go'
2--- server/acceptance/acceptanceclient.go 2015-04-16 12:16:51 +0000
3+++ server/acceptance/acceptanceclient.go 2015-06-04 16:25:32 +0000
4@@ -49,6 +49,8 @@
5 cookie string
6 cookieLock sync.RWMutex
7 ReportSetParams bool
8+ DontClose bool
9+ SlowStart time.Duration
10 // connection
11 Connection net.Conn
12 }
13@@ -101,7 +103,10 @@
14 // Run the session with the server, emits a stream of events.
15 func (sess *ClientSession) Run(events chan<- string) error {
16 conn := sess.Connection
17- defer conn.Close()
18+ if !sess.DontClose {
19+ defer conn.Close()
20+ }
21+ time.Sleep(sess.SlowStart)
22 conn.SetDeadline(time.Now().Add(sess.ExchangeTimeout))
23 _, err := conn.Write(wireVersionBytes)
24 if err != nil {
25
26=== modified file 'server/acceptance/cmd/acceptanceclient.go'
27--- server/acceptance/cmd/acceptanceclient.go 2014-08-20 19:48:59 +0000
28+++ server/acceptance/cmd/acceptanceclient.go 2015-06-04 16:25:32 +0000
29@@ -36,7 +36,7 @@
30 kit.Defaults["auth_helper"] = ""
31 kit.Defaults["wait_for"] = ""
32 cfg := &configuration{}
33- kit.CliLoop(cfg, &cfg.Configuration, func(session *acceptance.ClientSession, cfgDir string) {
34+ kit.CliLoop(cfg, &cfg.Configuration, func(session *acceptance.ClientSession, apiCli *kit.APIClient, cfgDir string) {
35 log.Printf("with: %#v", session)
36 }, func(url string) string {
37 if cfg.AuthHelper == "" {
38
39=== modified file 'server/acceptance/kit/api.go'
40--- server/acceptance/kit/api.go 2015-04-16 12:16:51 +0000
41+++ server/acceptance/kit/api.go 2015-06-04 16:25:32 +0000
42@@ -23,8 +23,10 @@
43 "crypto/tls"
44 "encoding/json"
45 "errors"
46+ "io"
47 "io/ioutil"
48 "net/http"
49+ "net/url"
50 )
51
52 // APIClient helps making api requests.
53@@ -56,6 +58,20 @@
54
55 var ErrNOk = errors.New("not ok")
56
57+func readBody(respBody io.ReadCloser) (map[string]interface{}, error) {
58+ defer respBody.Close()
59+ body, err := ioutil.ReadAll(respBody)
60+ if err != nil {
61+ return nil, err
62+ }
63+ var res map[string]interface{}
64+ err = json.Unmarshal(body, &res)
65+ if err != nil {
66+ return nil, &APIError{err.Error(), body}
67+ }
68+ return res, nil
69+}
70+
71 // Post a API request.
72 func (api *APIClient) PostRequest(path string, message interface{}) (map[string]interface{}, error) {
73 packedMessage, err := json.Marshal(message)
74@@ -77,18 +93,36 @@
75 if err != nil {
76 return nil, err
77 }
78- defer resp.Body.Close()
79- body, err := ioutil.ReadAll(resp.Body)
80+ res, err := readBody(resp.Body)
81 if err != nil {
82 return nil, err
83 }
84- var res map[string]interface{}
85- err = json.Unmarshal(body, &res)
86- if err != nil {
87- return nil, &APIError{err.Error(), body}
88- }
89+
90 if ok, _ := res["ok"].(bool); !ok {
91 return res, ErrNOk
92 }
93 return res, nil
94 }
95+
96+// Get resource from API endpoint.
97+func (api *APIClient) GetRequest(path string, params map[string]string) (map[string]interface{}, error) {
98+ apiURL := api.ServerAPIURL + path
99+ if len(params) != 0 {
100+ vals := url.Values{}
101+ for k, v := range params {
102+ vals.Set(k, v)
103+ }
104+ apiURL += "?" + vals.Encode()
105+ }
106+ request, _ := http.NewRequest("GET", apiURL, nil)
107+
108+ resp, err := api.httpClient.Do(request)
109+ if err != nil {
110+ return nil, err
111+ }
112+ res, err := readBody(resp.Body)
113+ if err != nil {
114+ return nil, err
115+ }
116+ return res, nil
117+}
118
119=== modified file 'server/acceptance/kit/cliloop.go'
120--- server/acceptance/kit/cliloop.go 2015-04-15 15:35:12 +0000
121+++ server/acceptance/kit/cliloop.go 2015-06-04 16:25:32 +0000
122@@ -17,6 +17,7 @@
123 package kit
124
125 import (
126+ "crypto/tls"
127 "flag"
128 "fmt"
129 "log"
130@@ -26,6 +27,8 @@
131 "strings"
132 "time"
133
134+ "launchpad.net/ubuntu-push/external/murmur3"
135+
136 "launchpad.net/ubuntu-push/config"
137 "launchpad.net/ubuntu-push/server/acceptance"
138 )
139@@ -39,6 +42,9 @@
140 CertPEMFile string `json:"cert_pem_file"`
141 Insecure bool `json:"insecure" help:"disable checking of server certificate and hostname"`
142 Domain string `json:"domain" help:"domain for tls connect"`
143+ // api config
144+ APIURL string `json:"api"`
145+ APICertPEMFile string `json:"api_cert_pem_file"`
146 // run timeout
147 RunTimeout config.ConfigTimeDuration `json:"run_timeout"`
148 // flags
149@@ -66,22 +72,24 @@
150 var (
151 Name = "acceptanceclient"
152 Defaults = map[string]interface{}{
153- "target": "",
154- "addr": ":0",
155- "exchange_timeout": "5s",
156- "cert_pem_file": "",
157- "insecure": false,
158- "domain": "",
159- "run_timeout": "0s",
160- "reportPings": true,
161- "model": "?",
162- "imageChannel": "?",
163- "buildNumber": -1,
164+ "target": "",
165+ "addr": ":0",
166+ "exchange_timeout": "5s",
167+ "cert_pem_file": "",
168+ "insecure": false,
169+ "domain": "",
170+ "run_timeout": "0s",
171+ "reportPings": true,
172+ "model": "?",
173+ "imageChannel": "?",
174+ "buildNumber": -1,
175+ "api": "",
176+ "api_cert_pem_file": "",
177 }
178 )
179
180 // CliLoop parses command line arguments and runs a client loop.
181-func CliLoop(totalCfg interface{}, cfg *Configuration, onSetup func(sess *acceptance.ClientSession, cfgDir string), auth func(string) string, waitFor func() string, onConnect func()) {
182+func CliLoop(totalCfg interface{}, cfg *Configuration, onSetup func(sess *acceptance.ClientSession, apiCli *APIClient, cfgDir string), auth func(string) string, waitFor func() string, onConnect func()) {
183 flag.Usage = func() {
184 fmt.Fprintf(os.Stderr, "Usage: %s [options] <device id>\n", Name)
185 flag.PrintDefaults()
186@@ -100,26 +108,57 @@
187 case narg < 1:
188 missingArg("device-id")
189 }
190+ cfgDir := filepath.Dir(flag.Lookup("cfg@").Value.String())
191+ // setup api
192+ apiCli := &APIClient{}
193+ var apiTLSConfig *tls.Config
194+ if cfg.APICertPEMFile != "" || cfg.Insecure {
195+ var err error
196+ apiTLSConfig, err = MakeTLSConfig("", cfg.Insecure,
197+ cfg.APICertPEMFile, cfgDir)
198+ if err != nil {
199+ log.Fatalf("api tls config: %v", err)
200+ }
201+ }
202+ apiCli.SetupClient(apiTLSConfig, true, 1)
203+ if cfg.APIURL == "" {
204+ apiCli.ServerAPIURL = cfg.PickByTarget("api",
205+ "https://push.ubuntu.com",
206+ "https://push.staging.ubuntu.com")
207+ } else {
208+ apiCli.ServerAPIURL = cfg.APIURL
209+ }
210+ deviceId := flag.Arg(0)
211 addr := ""
212+ domain := ""
213 if cfg.Addr == ":0" {
214- addr = cfg.PickByTarget("addr", "push-delivery.ubuntu.com:443",
215- "push-delivery.staging.ubuntu.com:443")
216+ hash := murmur3.Sum64([]byte(deviceId))
217+ hosts, err := apiCli.GetRequest("/delivery-hosts",
218+ map[string]string{
219+ "h": fmt.Sprintf("%x", hash),
220+ })
221+ if err != nil {
222+ log.Fatalf("querying hosts: %v", err)
223+ }
224+ addr = hosts["hosts"].([]interface{})[0].(string)
225+ domain = hosts["domain"].(string)
226+ log.Printf("using: %s %s", addr, domain)
227 } else {
228 addr = cfg.Addr.HostPort()
229+ domain = cfg.Domain
230 }
231 session := &acceptance.ClientSession{
232 ExchangeTimeout: cfg.ExchangeTimeout.TimeDuration(),
233 ServerAddr: addr,
234- DeviceId: flag.Arg(0),
235+ DeviceId: deviceId,
236 // flags
237 Model: cfg.DeviceModel,
238 ImageChannel: cfg.ImageChannel,
239 BuildNumber: cfg.BuildNumber,
240 ReportPings: cfg.ReportPings,
241 }
242- cfgDir := filepath.Dir(flag.Lookup("cfg@").Value.String())
243- onSetup(session, cfgDir)
244- session.TLSConfig, err = MakeTLSConfig(cfg.Domain, cfg.Insecure, cfg.CertPEMFile, cfgDir)
245+ onSetup(session, apiCli, cfgDir)
246+ session.TLSConfig, err = MakeTLSConfig(domain, cfg.Insecure, cfg.CertPEMFile, cfgDir)
247 if err != nil {
248 log.Fatalf("tls config: %v", err)
249 }

Subscribers

People subscribed via source and target branches