Archived
Merge pull request #1445 from calmh/compression
Compress only metadata by default (fixes #1374)
This commit is contained in:
commit
8cc70843a5
13 files changed
+247
-66
No files matched your search
Generated
+1
-1
@@ -31,7 +31,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/syncthing/protocol",
|
||||
"Rev": "cd0cce4195105cefab80fce84664188b614032e8"
|
||||
"Rev": "108b4e2e104610bdf416f2f156f35ee769276caf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2015 The Protocol Authors.
|
||||
|
||||
package protocol
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Compression int
|
||||
|
||||
const (
|
||||
CompressMetadata Compression = iota // zero value is the default, default should be "metadata"
|
||||
CompressNever
|
||||
CompressAlways
|
||||
|
||||
compressionThreshold = 128 // don't bother compressing messages smaller than this many bytes
|
||||
)
|
||||
|
||||
var compressionMarshal = map[Compression]string{
|
||||
CompressNever: "never",
|
||||
CompressMetadata: "metadata",
|
||||
CompressAlways: "always",
|
||||
}
|
||||
|
||||
var compressionUnmarshal = map[string]Compression{
|
||||
// Legacy
|
||||
"false": CompressNever,
|
||||
"true": CompressMetadata,
|
||||
|
||||
// Current
|
||||
"never": CompressNever,
|
||||
"metadata": CompressMetadata,
|
||||
"always": CompressAlways,
|
||||
}
|
||||
|
||||
func (c Compression) String() string {
|
||||
s, ok := compressionMarshal[c]
|
||||
if !ok {
|
||||
return fmt.Sprintf("unknown:%d", c)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (c Compression) GoString() string {
|
||||
return fmt.Sprintf("%q", c.String())
|
||||
}
|
||||
|
||||
func (c Compression) MarshalText() ([]byte, error) {
|
||||
return []byte(compressionMarshal[c]), nil
|
||||
}
|
||||
|
||||
func (c *Compression) UnmarshalText(bs []byte) error {
|
||||
*c = compressionUnmarshal[string(bs)]
|
||||
return nil
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2015 The Protocol Authors.
|
||||
|
||||
package protocol
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompressionMarshal(t *testing.T) {
|
||||
uTestcases := []struct {
|
||||
s string
|
||||
c Compression
|
||||
}{
|
||||
{"true", CompressMetadata},
|
||||
{"false", CompressNever},
|
||||
{"never", CompressNever},
|
||||
{"metadata", CompressMetadata},
|
||||
{"filedata", CompressFiledata},
|
||||
{"always", CompressAlways},
|
||||
{"whatever", CompressNever},
|
||||
}
|
||||
|
||||
mTestcases := []struct {
|
||||
s string
|
||||
c Compression
|
||||
}{
|
||||
{"never", CompressNever},
|
||||
{"metadata", CompressMetadata},
|
||||
{"filedata", CompressFiledata},
|
||||
{"always", CompressAlways},
|
||||
}
|
||||
|
||||
var c Compression
|
||||
for _, tc := range uTestcases {
|
||||
err := c.UnmarshalText([]byte(tc.s))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if c != tc.c {
|
||||
t.Errorf("%s unmarshalled to %d, not %d", tc.s, c, tc.c)
|
||||
}
|
||||
}
|
||||
|
||||
for _, tc := range mTestcases {
|
||||
bs, err := tc.c.MarshalText()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if s := string(bs); s != tc.s {
|
||||
t.Errorf("%d marshalled to %q, not %q", tc.c, s, tc.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-17
@@ -106,7 +106,7 @@ type rawConnection struct {
|
||||
closed chan struct{}
|
||||
once sync.Once
|
||||
|
||||
compressionThreshold int // compress messages larger than this many bytes
|
||||
compression Compression
|
||||
|
||||
rdbuf0 []byte // used & reused by readMessage
|
||||
rdbuf1 []byte // used & reused by readMessage
|
||||
@@ -135,25 +135,21 @@ const (
|
||||
pingIdleTime = 60 * time.Second
|
||||
)
|
||||
|
||||
func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, receiver Model, name string, compress bool) Connection {
|
||||
func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, receiver Model, name string, compress Compression) Connection {
|
||||
cr := &countingReader{Reader: reader}
|
||||
cw := &countingWriter{Writer: writer}
|
||||
|
||||
compThres := 1<<31 - 1 // compression disabled
|
||||
if compress {
|
||||
compThres = 128 // compress messages that are 128 bytes long or larger
|
||||
}
|
||||
c := rawConnection{
|
||||
id: deviceID,
|
||||
name: name,
|
||||
receiver: nativeModel{receiver},
|
||||
state: stateInitial,
|
||||
cr: cr,
|
||||
cw: cw,
|
||||
outbox: make(chan hdrMsg),
|
||||
nextID: make(chan int),
|
||||
closed: make(chan struct{}),
|
||||
compressionThreshold: compThres,
|
||||
id: deviceID,
|
||||
name: name,
|
||||
receiver: nativeModel{receiver},
|
||||
state: stateInitial,
|
||||
cr: cr,
|
||||
cw: cw,
|
||||
outbox: make(chan hdrMsg),
|
||||
nextID: make(chan int),
|
||||
closed: make(chan struct{}),
|
||||
compression: compress,
|
||||
}
|
||||
|
||||
go c.readerLoop()
|
||||
@@ -571,7 +567,15 @@ func (c *rawConnection) writerLoop() {
|
||||
return
|
||||
}
|
||||
|
||||
if len(uncBuf) >= c.compressionThreshold {
|
||||
compress := false
|
||||
switch c.compression {
|
||||
case CompressAlways:
|
||||
compress = true
|
||||
case CompressMetadata:
|
||||
compress = hm.hdr.msgType != messageTypeResponse
|
||||
}
|
||||
|
||||
if compress && len(uncBuf) >= compressionThreshold {
|
||||
// Use compression for large messages
|
||||
hm.hdr.compression = true
|
||||
|
||||
|
||||
+10
-10
@@ -67,8 +67,8 @@ func TestPing(t *testing.T) {
|
||||
ar, aw := io.Pipe()
|
||||
br, bw := io.Pipe()
|
||||
|
||||
c0 := NewConnection(c0ID, ar, bw, nil, "name", true).(wireFormatConnection).next.(*rawConnection)
|
||||
c1 := NewConnection(c1ID, br, aw, nil, "name", true).(wireFormatConnection).next.(*rawConnection)
|
||||
c0 := NewConnection(c0ID, ar, bw, nil, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
|
||||
c1 := NewConnection(c1ID, br, aw, nil, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
|
||||
|
||||
if ok := c0.ping(); !ok {
|
||||
t.Error("c0 ping failed")
|
||||
@@ -91,8 +91,8 @@ func TestPingErr(t *testing.T) {
|
||||
eaw := &ErrPipe{PipeWriter: *aw, max: i, err: e}
|
||||
ebw := &ErrPipe{PipeWriter: *bw, max: j, err: e}
|
||||
|
||||
c0 := NewConnection(c0ID, ar, ebw, m0, "name", true).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, eaw, m1, "name", true)
|
||||
c0 := NewConnection(c0ID, ar, ebw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, eaw, m1, "name", CompressAlways)
|
||||
|
||||
res := c0.ping()
|
||||
if (i < 8 || j < 8) && res {
|
||||
@@ -167,8 +167,8 @@ func TestVersionErr(t *testing.T) {
|
||||
ar, aw := io.Pipe()
|
||||
br, bw := io.Pipe()
|
||||
|
||||
c0 := NewConnection(c0ID, ar, bw, m0, "name", true).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, aw, m1, "name", true)
|
||||
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, aw, m1, "name", CompressAlways)
|
||||
|
||||
w := xdr.NewWriter(c0.cw)
|
||||
w.WriteUint32(encodeHeader(header{
|
||||
@@ -190,8 +190,8 @@ func TestTypeErr(t *testing.T) {
|
||||
ar, aw := io.Pipe()
|
||||
br, bw := io.Pipe()
|
||||
|
||||
c0 := NewConnection(c0ID, ar, bw, m0, "name", true).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, aw, m1, "name", true)
|
||||
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, aw, m1, "name", CompressAlways)
|
||||
|
||||
w := xdr.NewWriter(c0.cw)
|
||||
w.WriteUint32(encodeHeader(header{
|
||||
@@ -213,8 +213,8 @@ func TestClose(t *testing.T) {
|
||||
ar, aw := io.Pipe()
|
||||
br, bw := io.Pipe()
|
||||
|
||||
c0 := NewConnection(c0ID, ar, bw, m0, "name", true).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, aw, m1, "name", true)
|
||||
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
|
||||
NewConnection(c1ID, br, aw, m1, "name", CompressAlways)
|
||||
|
||||
c0.close(nil)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"Add new folder?": "Add new folder?",
|
||||
"Address": "Address",
|
||||
"Addresses": "Addresses",
|
||||
"All Data": "All Data",
|
||||
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
|
||||
"Anonymous Usage Reporting": "Anonymous Usage Reporting",
|
||||
"Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.",
|
||||
@@ -16,6 +17,7 @@
|
||||
"Changelog": "Changelog",
|
||||
"Close": "Close",
|
||||
"Comment, when used at the start of a line": "Comment, when used at the start of a line",
|
||||
"Compression": "Compression",
|
||||
"Compression is recommended in most setups.": "Compression is recommended in most setups.",
|
||||
"Connection Error": "Connection Error",
|
||||
"Copied from elsewhere": "Copied from elsewhere",
|
||||
@@ -71,6 +73,7 @@
|
||||
"Local Discovery": "Local Discovery",
|
||||
"Local State": "Local State",
|
||||
"Maximum Age": "Maximum Age",
|
||||
"Metadata Only": "Metadata Only",
|
||||
"Move to top of queue": "Move to top of queue",
|
||||
"Multi level wildcard (matches multiple directory levels)": "Multi level wildcard (matches multiple directory levels)",
|
||||
"Never": "Never",
|
||||
@@ -80,6 +83,7 @@
|
||||
"No File Versioning": "No File Versioning",
|
||||
"Notice": "Notice",
|
||||
"OK": "OK",
|
||||
"Off": "Off",
|
||||
"Offline": "Offline",
|
||||
"Online": "Online",
|
||||
"Out Of Sync": "Out Of Sync",
|
||||
|
||||
+12
-9
@@ -370,9 +370,12 @@
|
||||
<th><span class="glyphicon glyphicon-link"></span> <span translate>Address</span></th>
|
||||
<td class="text-right">{{deviceAddr(deviceCfg)}}</td>
|
||||
</tr>
|
||||
<tr ng-if="!deviceCfg.Compression">
|
||||
<th><span class="glyphicon glyphicon-compressed"></span> <span translate>Use Compression</span></th>
|
||||
<td translate class="text-right">No</td>
|
||||
<tr ng-if="deviceCfg.Compression != 'metadata'">
|
||||
<th><span class="glyphicon glyphicon-compressed"></span> <span translate>Compression</span></th>
|
||||
<td class="text-right">
|
||||
<span ng-if="deviceCfg.Compression == 'always'" translate>All Data</span>
|
||||
<span ng-if="deviceCfg.Compression == 'never'" translate>Off</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="deviceCfg.Introducer">
|
||||
<th><span class="glyphicon glyphicon-thumbs-up"></span> <span translate>Introducer</span></th>
|
||||
@@ -502,12 +505,12 @@
|
||||
<p translate class="help-block">Enter comma separated "ip:port" addresses or "dynamic" to perform automatic discovery of the address.</p>
|
||||
</div>
|
||||
<div ng-if="!editingSelf" class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="currentDevice.Compression"> <span translate>Use Compression</span>
|
||||
</label>
|
||||
<p translate class="help-block">Compression is recommended in most setups.</p>
|
||||
</div>
|
||||
<label translate>Compression</label>
|
||||
<select class="form-control" ng-model="currentDevice.Compression">
|
||||
<option value="always" translate>All Data</option>
|
||||
<option value="metadata" translate>Metadata Only</option>
|
||||
<option value="never" translate>Off</option>
|
||||
</select>
|
||||
</div>
|
||||
<div ng-if="!editingSelf" class="form-group">
|
||||
<div class="checkbox">
|
||||
|
||||
@@ -713,7 +713,7 @@ angular.module('syncthing.core')
|
||||
.then(function () {
|
||||
$scope.currentDevice = {
|
||||
AddressesStr: 'dynamic',
|
||||
Compression: true,
|
||||
Compression: 'metadata',
|
||||
Introducer: false,
|
||||
selectedFolders: {}
|
||||
};
|
||||
@@ -758,7 +758,7 @@ angular.module('syncthing.core')
|
||||
var deviceCfg = {
|
||||
DeviceID: device,
|
||||
AddressesStr: 'dynamic',
|
||||
Compression: true,
|
||||
Compression: 'metadata',
|
||||
Introducer: false,
|
||||
selectedFolders: {}
|
||||
};
|
||||
|
||||
@@ -177,7 +177,7 @@ func Assets() map[string][]byte {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
assets["assets/lang/valid-langs.js"] = bs
|
||||
|
||||
bs, _ = base64.StdEncoding.DecodeString("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 truncated
|
||||
bs, _ = base64.StdEncoding.DecodeString("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 truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewReader(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
assets["index.html"] = bs
|
||||
@@ -197,7 +197,7 @@ func Assets() map[string][]byte {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
assets["scripts/syncthing/core/controllers/eventController.js"] = bs
|
||||
|
||||
bs, _ = base64.StdEncoding.DecodeString("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 truncated
|
||||
bs, _ = base64.StdEncoding.DecodeString("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 truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewReader(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
assets["scripts/syncthing/core/controllers/syncthingController.js"] = bs
|
||||
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
|
||||
var l = logger.DefaultLogger
|
||||
|
||||
const CurrentVersion = 8
|
||||
const CurrentVersion = 9
|
||||
|
||||
type Configuration struct {
|
||||
Version int `xml:"version,attr"`
|
||||
@@ -146,12 +146,12 @@ func (c *VersioningConfiguration) UnmarshalXML(d *xml.Decoder, start xml.StartEl
|
||||
}
|
||||
|
||||
type DeviceConfiguration struct {
|
||||
DeviceID protocol.DeviceID `xml:"id,attr"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Addresses []string `xml:"address,omitempty"`
|
||||
Compression bool `xml:"compression,attr"`
|
||||
CertName string `xml:"certName,attr,omitempty"`
|
||||
Introducer bool `xml:"introducer,attr"`
|
||||
DeviceID protocol.DeviceID `xml:"id,attr"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Addresses []string `xml:"address,omitempty"`
|
||||
Compression protocol.Compression `xml:"compression,attr"`
|
||||
CertName string `xml:"certName,attr,omitempty"`
|
||||
Introducer bool `xml:"introducer,attr"`
|
||||
}
|
||||
|
||||
type FolderDeviceConfiguration struct {
|
||||
@@ -320,6 +320,9 @@ func (cfg *Configuration) prepare(myID protocol.DeviceID) {
|
||||
if cfg.Version == 7 {
|
||||
convertV7V8(cfg)
|
||||
}
|
||||
if cfg.Version == 8 {
|
||||
convertV8V9(cfg)
|
||||
}
|
||||
|
||||
// Hash old cleartext passwords
|
||||
if len(cfg.GUI.Password) > 0 && cfg.GUI.Password[0] != '$' {
|
||||
@@ -411,6 +414,13 @@ func ChangeRequiresRestart(from, to Configuration) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func convertV8V9(cfg *Configuration) {
|
||||
// Compression is interpreted and serialized differently, but no enforced
|
||||
// changes. Still need a new version number since the compression stuff
|
||||
// isn't understandable by earlier versions.
|
||||
cfg.Version = 9
|
||||
}
|
||||
|
||||
func convertV7V8(cfg *Configuration) {
|
||||
// Add IPv6 announce server
|
||||
if len(cfg.Options.GlobalAnnServers) == 1 && cfg.Options.GlobalAnnServers[0] == "udp4://announce.syncthing.net:22026" {
|
||||
@@ -498,7 +508,7 @@ func convertV2V3(cfg *Configuration) {
|
||||
// compression on all existing new. New devices will get compression on by
|
||||
// default by the GUI.
|
||||
for i := range cfg.Deprecated_Nodes {
|
||||
cfg.Deprecated_Nodes[i].Compression = true
|
||||
cfg.Deprecated_Nodes[i].Compression = protocol.CompressMetadata
|
||||
}
|
||||
|
||||
// The global discovery format and port number changed in v0.9. Having the
|
||||
|
||||
@@ -99,13 +99,13 @@ func TestDeviceConfig(t *testing.T) {
|
||||
DeviceID: device1,
|
||||
Name: "node one",
|
||||
Addresses: []string{"a"},
|
||||
Compression: true,
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
{
|
||||
DeviceID: device4,
|
||||
Name: "node two",
|
||||
Addresses: []string{"b"},
|
||||
Compression: true,
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
}
|
||||
expectedDeviceIDs := []protocol.DeviceID{device1, device4}
|
||||
@@ -176,24 +176,22 @@ func TestDeviceAddressesDynamic(t *testing.T) {
|
||||
name, _ := os.Hostname()
|
||||
expected := map[protocol.DeviceID]DeviceConfiguration{
|
||||
device1: {
|
||||
DeviceID: device1,
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: true,
|
||||
DeviceID: device1,
|
||||
Addresses: []string{"dynamic"},
|
||||
},
|
||||
device2: {
|
||||
DeviceID: device2,
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: true,
|
||||
DeviceID: device2,
|
||||
Addresses: []string{"dynamic"},
|
||||
},
|
||||
device3: {
|
||||
DeviceID: device3,
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: true,
|
||||
DeviceID: device3,
|
||||
Addresses: []string{"dynamic"},
|
||||
},
|
||||
device4: {
|
||||
DeviceID: device4,
|
||||
Name: name, // Set when auto created
|
||||
Addresses: []string{"dynamic"},
|
||||
DeviceID: device4,
|
||||
Name: name, // Set when auto created
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -208,6 +206,43 @@ func TestDeviceAddressesDynamic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeviceCompression(t *testing.T) {
|
||||
name, _ := os.Hostname()
|
||||
expected := map[protocol.DeviceID]DeviceConfiguration{
|
||||
device1: {
|
||||
DeviceID: device1,
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
device2: {
|
||||
DeviceID: device2,
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
device3: {
|
||||
DeviceID: device3,
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: protocol.CompressNever,
|
||||
},
|
||||
device4: {
|
||||
DeviceID: device4,
|
||||
Name: name, // Set when auto created
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
}
|
||||
|
||||
cfg, err := Load("testdata/devicecompression.xml", device4)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
actual := cfg.Devices()
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Devices differ;\n E: %#v\n A: %#v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeviceAddressesStatic(t *testing.T) {
|
||||
name, _ := os.Hostname()
|
||||
expected := map[protocol.DeviceID]DeviceConfiguration{
|
||||
@@ -224,9 +259,10 @@ func TestDeviceAddressesStatic(t *testing.T) {
|
||||
Addresses: []string{"[2001:db8::44]:4444", "192.0.2.4:6090"},
|
||||
},
|
||||
device4: {
|
||||
DeviceID: device4,
|
||||
Name: name, // Set when auto created
|
||||
Addresses: []string{"dynamic"},
|
||||
DeviceID: device4,
|
||||
Name: name, // Set when auto created
|
||||
Addresses: []string{"dynamic"},
|
||||
Compression: protocol.CompressMetadata,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<configuration version="5">
|
||||
<device id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ" compression="true">
|
||||
</device>
|
||||
<device id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA" compression="metadata">
|
||||
</device>
|
||||
<device id="LGFPDIT7SKNNJVJZA4FC7QNCRKCE753K72BW5QD2FOZ7FRFEP57Q" compression="false">
|
||||
</device>
|
||||
</configuration>
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
<configuration version="9">
|
||||
<folder id="test" path="testdata" ro="true" ignorePerms="false" rescanIntervalS="600">
|
||||
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
|
||||
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"></device>
|
||||
</folder>
|
||||
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="metadata">
|
||||
<address>a</address>
|
||||
</device>
|
||||
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" name="node two" compression="metadata">
|
||||
<address>b</address>
|
||||
</device>
|
||||
</configuration>
|
||||
Reference in new issue
Block a user