diff options
Diffstat (limited to 'plugin/torrent')
-rw-r--r-- | plugin/torrent/README.md | 48 | ||||
-rw-r--r-- | plugin/torrent/session.go | 25 | ||||
-rw-r--r-- | plugin/torrent/setup.go | 58 | ||||
-rw-r--r-- | plugin/torrent/setup_test.go | 53 | ||||
-rw-r--r-- | plugin/torrent/torrent.go | 9 |
5 files changed, 193 insertions, 0 deletions
diff --git a/plugin/torrent/README.md b/plugin/torrent/README.md new file mode 100644 index 000000000..890bb8e3b --- /dev/null +++ b/plugin/torrent/README.md @@ -0,0 +1,48 @@ +# torrent + +## Name + +*torrent* - use BitTorrent to disseminate zone data. + +## Description + +The *torrent* plugin uses the BitTorrent protocol to disseminate zone data. Multiple peers can +connect and down- and upload the data. A couple of nodes can be `seed` only meaning they will update +the torrent when their zone data changes. Non-`seed` peers will write received data back into the +zonefile - once the torrent is fully downloaded. + +## Syntax + +The simplest syntax is for a peer wanting to receive the zone data: + +~~~ txt +torrent DBFILE +~~~ + +* **DBFILE** the zone database file to torrent. If the path is relative, the path from the + *root* plugin will be prepended to it. + +For peers seeding the torrent use this, slightly expanded, syntax + +~~~ txt +torrent DBFILE { + seed +} +~~~ + +* `seed` tells *torrent* to seed content from **DBFILE** to the peers, it will _never_ write to + **DBFILE**. When `seed` is _not_ specified **DBFILE** will be written to once the entire torrent + is downloaded. + +## Examples + +~~~ txt +example.org { + file db.example.org + torrent db.example.org +} +~~~ + +## Also See + +## Bugs diff --git a/plugin/torrent/session.go b/plugin/torrent/session.go new file mode 100644 index 000000000..3b3a35a41 --- /dev/null +++ b/plugin/torrent/session.go @@ -0,0 +1,25 @@ +package torrent + +import ( + "log" + "time" + + rtorrent "github.com/cenkalti/rain/torrent" +) + +func (t *Torrent) StartSession() error { + s, err := rtorrent.NewSession(torrent.DefaultConfig) + if err != nil { + return err + } + + // Add magnet link + tor, _ := ses.AddURI(magnetLink, nil) + + // Watch the progress + for range time.Tick(time.Second) { + s := tor.Stats() + log.Printf("Status: %s, Downloaded: %d, Peers: %d", s.Status.String(), s.Bytes.Completed, s.Peers.Total) + } + +} diff --git a/plugin/torrent/setup.go b/plugin/torrent/setup.go new file mode 100644 index 000000000..ac69f0e96 --- /dev/null +++ b/plugin/torrent/setup.go @@ -0,0 +1,58 @@ +package torrent + +import ( + "path/filepath" + + "github.com/coredns/coredns/core/dnsserver" + "github.com/coredns/coredns/plugin" + + "github.com/caddyserver/caddy" +) + +func init() { plugin.Register("torrent", setup) } + +func setup(c *caddy.Controller) error { + tor, err := parse(c) + if err != nil { + return plugin.Error("sign", err) + } + + c.OnStartup(func() error { + // go tor.do() + return nil + }) + c.OnShutdown(func() error { + close(tor.stop) + return nil + }) + + // Don't call AddPlugin, *sign* is not a plugin. + return nil +} + +func parse(c *caddy.Controller) (*Torrent, error) { + t := &Torrent{} + config := dnsserver.GetConfig(c) + + for c.Next() { + if !c.NextArg() { + return nil, c.ArgErr() + } + dbfile := c.Val() + if !filepath.IsAbs(dbfile) && config.Root != "" { + dbfile = filepath.Join(config.Root, dbfile) + } + t.dbfile = dbfile + + for c.NextBlock() { + switch c.Val() { + case "seed": + t.seed = true + default: + return nil, c.Errf("unknown property '%s'", c.Val()) + } + } + } + + return t, nil +} diff --git a/plugin/torrent/setup_test.go b/plugin/torrent/setup_test.go new file mode 100644 index 000000000..3faa336fd --- /dev/null +++ b/plugin/torrent/setup_test.go @@ -0,0 +1,53 @@ +package torrent + +import ( + "testing" + + "github.com/caddyserver/caddy" +) + +func TestParse(t *testing.T) { + tests := []struct { + input string + shouldErr bool + exp *Torrent + }{ + {`torrent testdata/db.miek.nl { + seed + }`, + false, + &Torrent{dbfile: "testdata/db.miek.nl", seed: true}, + }, + {`torrent testdata/db.miek.nl`, + false, + &Torrent{dbfile: "testdata/db.miek.nl"}, + }, + // errors + {`torrent db.example.org { + bla + }`, + true, + nil, + }, + } + for i, tc := range tests { + c := caddy.NewTestController("dns", tc.input) + tor, err := parse(c) + + if err == nil && tc.shouldErr { + t.Fatalf("Test %d expected errors, but got no error", i) + } + if err != nil && !tc.shouldErr { + t.Fatalf("Test %d expected no errors, but got '%v'", i, err) + } + if tc.shouldErr { + continue + } + if x := tor.dbfile; x != tc.exp.dbfile { + t.Errorf("Test %d expected %s as dbfile, got %s", i, tc.exp.dbfile, x) + } + if x := tor.seed; x != tc.exp.seed { + t.Errorf("Test %d expected %T as seed, got %T", i, tc.exp.seed, x) + } + } +} diff --git a/plugin/torrent/torrent.go b/plugin/torrent/torrent.go new file mode 100644 index 000000000..91453ce22 --- /dev/null +++ b/plugin/torrent/torrent.go @@ -0,0 +1,9 @@ +package torrent + +// Torrent contains the file data that needs to be torrented. +type Torrent struct { + dbfile string + seed bool + + stop chan struct{} +} |