Skip to content

Commit 515f2c7

Browse files
Merge pull request #12 from cybozu-go/cmd
Use the command framework
2 parents be4cec5 + c9291ce commit 515f2c7

23 files changed

+264
-247
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
sudo: false
22
language: go
33
go:
4-
- 1.6
4+
- 1.7
55
- tip
66

77
before_install:
@@ -24,5 +24,5 @@ deploy:
2424
- ${GO_APT_MIRROR}
2525
skip_cleanup: true
2626
on:
27-
go: 1.6
27+
go: 1.7
2828
tags: true

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [Unreleased]
6+
### Added
7+
- aptuitl now adopts [github.com/cybozu-go/cmd][cmd] framework.
8+
As a result, commands implement [the common spec][spec].
9+
- [cacher] added `listen_address` configuration parameter to specify listening address (#9).
10+
- [cacher] added `log` configuration section to specify logging options.
11+
- [mirror] added `log` configuration section to specify logging options.
12+
13+
### Changed
14+
- aptutil now requires Go 1.7 or better.
15+
16+
### Removed
17+
- [cacher] `-s` and `-l` command-line flags are gone.
18+
- [mirror] `-s` command-line flag is gone.
19+
20+
## [1.1.0]
21+
### Changed
22+
- Update docs (kudos to @xipmix).
23+
- [cacher] extend Release file check interval from 15 to 600 seconds (#8).
24+
25+
## [1.0.1]
26+
### Changed
27+
- [mirror] ignore Sources if `include_source` is not specified in mirror.toml.
28+
This works as a workaround for some badly configured web servers.
29+
30+
31+
[cmd]: https://github.com/cybozu-go/cmd
32+
[spec]: https://github.com/cybozu-go/cmd/blob/master/README.md#specifications
33+
[Unreleased]: https://github.com/cybozu-go/aptutil/compare/v1.1.0...HEAD
34+
[1.1.0]: https://github.com/cybozu-go/aptutil/compare/v1.0.1...v1.1.0
35+
[1.0.1]: https://github.com/cybozu-go/aptutil/compare/v1.0.0...v1.0.1

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Usage
4646
Build
4747
-----
4848

49-
Use Go 1.6 or better.
49+
Use Go 1.7 or better.
5050

5151
Run the command below exactly as shown, including the ellipsis.
5252
They are significant - see `go help packages`.

cacher/cacher.go

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package cacher
55

66
import (
77
"bytes"
8+
"context"
89
"io/ioutil"
910
"net/http"
1011
"net/url"
@@ -18,8 +19,6 @@ import (
1819
"github.com/cybozu-go/aptutil/apt"
1920
"github.com/cybozu-go/log"
2021
"github.com/pkg/errors"
21-
"golang.org/x/net/context"
22-
"golang.org/x/net/context/ctxhttp"
2322
)
2423

2524
const (
@@ -60,15 +59,11 @@ type Cacher struct {
6059

6160
// NewCacher constructs Cacher.
6261
func NewCacher(ctx context.Context, config *Config) (*Cacher, error) {
63-
checkInterval := time.Duration(config.CheckInterval) * time.Second
64-
if checkInterval == 0 {
65-
checkInterval = defaultCheckInterval * time.Second
62+
if config.CheckInterval == 0 {
63+
return nil, errors.New("invaild check_interval")
6664
}
67-
65+
checkInterval := time.Duration(config.CheckInterval) * time.Second
6866
cachePeriod := time.Duration(config.CachePeriod) * time.Second
69-
if cachePeriod == 0 {
70-
cachePeriod = defaultCachePeriod * time.Second
71-
}
7267

7368
metaDir := filepath.Clean(config.MetaDirectory)
7469
if !filepath.IsAbs(metaDir) {
@@ -84,10 +79,10 @@ func NewCacher(ctx context.Context, config *Config) (*Cacher, error) {
8479
return nil, errors.New("meta_dir and cache_dir must be different")
8580
}
8681

87-
capacity := uint64(config.CacheCapacity) * gib
88-
if capacity == 0 {
89-
capacity = defaultCacheCapacity * gib
82+
if config.CacheCapacity <= 0 {
83+
return nil, errors.New("cache_capacity must be > 0")
9084
}
85+
capacity := uint64(config.CacheCapacity) * gib
9186

9287
meta := NewStorage(metaDir, 0)
9388
cache := NewStorage(cacheDir, capacity)
@@ -206,7 +201,7 @@ func (c *Cacher) maintRelease(p string, withGPG bool) {
206201

207202
if log.Enabled(log.LvDebug) {
208203
log.Debug("maintRelease", map[string]interface{}{
209-
"_path": p,
204+
"path": p,
210205
})
211206
}
212207

@@ -287,11 +282,19 @@ func (c *Cacher) download(p string, u *url.URL, valid *apt.FileInfo) {
287282
ctx, cancel := context.WithTimeout(c.ctx, requestTimeout)
288283
defer cancel()
289284

290-
resp, err := ctxhttp.Get(ctx, c.client, u.String())
285+
req := &http.Request{
286+
Method: "GET",
287+
URL: u,
288+
Proto: "HTTP/1.1",
289+
ProtoMajor: 1,
290+
ProtoMinor: 1,
291+
Header: make(http.Header),
292+
}
293+
resp, err := c.client.Do(req.WithContext(ctx))
291294
if err != nil {
292295
log.Warn("GET failed", map[string]interface{}{
293-
"_url": u.String(),
294-
"_err": err.Error(),
296+
"url": u.String(),
297+
"error": err.Error(),
295298
})
296299
return
297300
}
@@ -305,16 +308,16 @@ func (c *Cacher) download(p string, u *url.URL, valid *apt.FileInfo) {
305308

306309
if err != nil {
307310
log.Warn("GET failed", map[string]interface{}{
308-
"_url": u.String(),
309-
"_err": err.Error(),
311+
"url": u.String(),
312+
"error": err.Error(),
310313
})
311314
return
312315
}
313316

314317
fi := apt.MakeFileInfo(p, body)
315318
if valid != nil && !valid.Same(fi) {
316319
log.Warn("downloaded data is not valid", map[string]interface{}{
317-
"_url": u.String(),
320+
"url": u.String(),
318321
})
319322
return
320323
}
@@ -331,8 +334,8 @@ func (c *Cacher) download(p string, u *url.URL, valid *apt.FileInfo) {
331334
fil, err = apt.ExtractFileInfo(t[1], bytes.NewReader(body))
332335
if err != nil {
333336
log.Error("invalid meta data", map[string]interface{}{
334-
"_path": p,
335-
"_err": err.Error(),
337+
"path": p,
338+
"error": err.Error(),
336339
})
337340
// do not return; we accept broken meta data as is.
338341
}
@@ -344,8 +347,8 @@ func (c *Cacher) download(p string, u *url.URL, valid *apt.FileInfo) {
344347

345348
if err := storage.Insert(body, fi); err != nil {
346349
log.Error("could not save an item", map[string]interface{}{
347-
"_path": p,
348-
"_err": err.Error(),
350+
"path": p,
351+
"error": err.Error(),
349352
})
350353
// panic because go-apt-cacher cannot continue working
351354
panic(err)
@@ -363,7 +366,7 @@ func (c *Cacher) download(p string, u *url.URL, valid *apt.FileInfo) {
363366
}
364367
c.info[p] = fi
365368
log.Info("downloaded and cached", map[string]interface{}{
366-
"_path": p,
369+
"path": p,
367370
})
368371
}
369372

@@ -401,7 +404,7 @@ RETRY:
401404
case ErrNotFound:
402405
default:
403406
log.Error("lookup failure", map[string]interface{}{
404-
"_err": err.Error(),
407+
"error": err.Error(),
405408
})
406409
return http.StatusInternalServerError, nil, err
407410
}

cacher/config.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package cacher
22

3+
import "github.com/cybozu-go/cmd"
4+
35
const (
6+
defaultAddress = ":3142"
47
defaultCheckInterval = 600
58
defaultCachePeriod = 3
69
defaultCacheCapacity = 1
@@ -11,12 +14,17 @@ const (
1114
//
1215
// Use https://github.com/BurntSushi/toml as follows:
1316
//
14-
// var config cacher.Config
15-
// md, err := toml.DecodeFile("/path/to/config.toml", &config)
17+
// config := cacher.NewConfig()
18+
// md, err := toml.DecodeFile("/path/to/config.toml", config)
1619
// if err != nil {
1720
// ...
1821
// }
1922
type Config struct {
23+
// Addr is the listening address of HTTP server.
24+
//
25+
// Default is ":3142".
26+
Addr string `toml:"listen_address"`
27+
2028
// CheckInterval specifies interval in seconds to check updates for
2129
// Release/InRelease files.
2230
//
@@ -49,6 +57,20 @@ type Config struct {
4957
// Zero disables limit on the number of connections.
5058
MaxConns int `toml:"max_conns"`
5159

60+
// Log is cmd.LogConfig
61+
Log cmd.LogConfig `toml:"log"`
62+
5263
// Mapping specifies mapping between prefixes and APT URLs.
5364
Mapping map[string]string `toml:"mapping"`
5465
}
66+
67+
// NewConfig creates Config with default values.
68+
func NewConfig() *Config {
69+
return &Config{
70+
Addr: defaultAddress,
71+
CheckInterval: defaultCheckInterval,
72+
CachePeriod: defaultCachePeriod,
73+
CacheCapacity: defaultCacheCapacity,
74+
MaxConns: defaultMaxConns,
75+
}
76+
}

cacher/config_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
func TestConfig(t *testing.T) {
1010
t.Parallel()
1111

12-
var config Config
12+
config := NewConfig()
1313
md, err := toml.DecodeFile("t/cacher.toml", &config)
1414
if err != nil {
1515
t.Fatal(err)
@@ -34,8 +34,12 @@ func TestConfig(t *testing.T) {
3434
if config.CacheCapacity != 21 {
3535
t.Error(`config.CacheCapacity != 21`)
3636
}
37-
if config.MaxConns != 3 {
38-
t.Error(`config.MaxConns != 3`)
37+
if config.MaxConns != defaultMaxConns {
38+
t.Error(`config.MaxConns != defaultMaxConns`)
39+
}
40+
41+
if config.Log.Level != "error" {
42+
t.Error(`config.Log.Level != "error"`)
3943
}
4044

4145
if config.Mapping["ubuntu"] != "http://archive.ubuntu.com/ubuntu" {

cacher/handler.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ func (c cacheHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
2424
return
2525
}
2626

27-
accepted := time.Now()
2827
p := path.Clean(r.URL.Path[1:])
2928

3029
if log.Enabled(log.LvDebug) {
3130
log.Debug("request path", map[string]interface{}{
32-
"_path": p,
31+
"path": p,
3332
})
3433
}
3534

@@ -48,13 +47,13 @@ func (c cacheHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
4847
if r.Method == "GET" {
4948
var zeroTime time.Time
5049
http.ServeContent(w, r, path.Base(p), zeroTime, f)
51-
goto LOG
50+
return
5251
}
5352
stat, err := f.Stat()
5453
if err != nil {
5554
status = http.StatusInternalServerError
5655
http.Error(w, err.Error(), status)
57-
goto LOG
56+
return
5857
}
5958
ct := mime.TypeByExtension(path.Ext(p))
6059
if ct == "" {
@@ -64,14 +63,4 @@ func (c cacheHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6463
w.Header().Set("Content-Length", strconv.FormatInt(stat.Size(), 10))
6564
w.WriteHeader(http.StatusOK)
6665
}
67-
68-
LOG:
69-
took := time.Now().Sub(accepted)
70-
log.Info("[http]", map[string]interface{}{
71-
"_method": r.Method,
72-
"_elapsed": took.String(),
73-
"_path": p,
74-
"_status": status,
75-
"_remote_addr": r.RemoteAddr,
76-
})
7766
}

cacher/server.go

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,22 @@
11
package cacher
22

33
import (
4-
_log "log"
5-
"net"
64
"net/http"
7-
"time"
85

9-
"github.com/cybozu-go/log"
10-
"github.com/facebookgo/httpdown"
11-
"golang.org/x/net/context"
6+
"github.com/cybozu-go/cmd"
127
)
138

14-
const (
15-
defaultReadTimeout = 10 * time.Second
16-
defaultWriteTimeout = 10 * time.Second
17-
)
18-
19-
// Serve runs REST API server until ctx.Done() is closed.
20-
func Serve(ctx context.Context, l net.Listener, c *Cacher) error {
21-
hd := httpdown.HTTP{}
22-
logger := _log.New(log.DefaultLogger().Writer(log.LvError), "[http]", 0)
23-
s := &http.Server{
24-
Handler: cacheHandler{c},
25-
ReadTimeout: defaultReadTimeout,
26-
WriteTimeout: defaultWriteTimeout,
27-
ErrorLog: logger,
9+
// NewServer returns HTTPServer implements go-apt-cacher handlers.
10+
func NewServer(c *Cacher, config *Config) *cmd.HTTPServer {
11+
addr := config.Addr
12+
if len(addr) == 0 {
13+
addr = defaultAddress
2814
}
29-
hs := hd.Serve(s, l)
30-
31-
waiterr := make(chan error, 1)
32-
go func() {
33-
defer close(waiterr)
34-
waiterr <- hs.Wait()
35-
}()
36-
37-
select {
38-
case err := <-waiterr:
39-
return err
4015

41-
case <-ctx.Done():
42-
if err := hs.Stop(); err != nil {
43-
return err
44-
}
45-
return <-waiterr
16+
return &cmd.HTTPServer{
17+
Server: &http.Server{
18+
Addr: addr,
19+
Handler: cacheHandler{c},
20+
},
4621
}
4722
}

0 commit comments

Comments
 (0)