diff --git a/conn.go b/conn.go index 532a4b348..90b24be84 100644 --- a/conn.go +++ b/conn.go @@ -20,6 +20,7 @@ package main import ( "bytes" "encoding/json" + "errors" "fmt" "net/http" "os" @@ -170,8 +171,7 @@ func uploadHandler(c *gin.Context) { // Upload if data.Extra.Network { - send(map[string]string{uploadStatusStr: "Starting", "Cmd": "Network"}) - err = upload.Network(data.Port, data.Board, filePaths, commandline, data.Extra.Auth, l, data.Extra.SSH) + err = errors.New("network upload is not supported anymore, pease use OTA instead") } else { send(map[string]string{uploadStatusStr: "Starting", "Cmd": "Serial"}) err = upload.Serial(data.Port, commandline, data.Extra, l) diff --git a/discovery.go b/discovery.go deleted file mode 100644 index 1856ea9b5..000000000 --- a/discovery.go +++ /dev/null @@ -1,156 +0,0 @@ -// -// discovery.go -// -// Created by Martino Facchin -// Copyright (c) 2015 Arduino LLC -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -package main - -import ( - "net" - "strings" - "time" - - "github.com/oleksandr/bonjour" - log "github.com/sirupsen/logrus" -) - -const timeoutConst = 2 - -// SavedNetworkPorts contains the ports which we know are already connected -var SavedNetworkPorts []OsSerialPort - -// enumerateNetworkPorts returns a list of Network Ports -// The research of network ports is articulated in two phases. First we add new ports coming from -// the bonjour module, then we prune the boards who don't respond to a ping -func enumerateNetworkPorts() ([]OsSerialPort, error) { - newPorts, err := getPorts() - if err != nil { - return nil, err - } - - SavedNetworkPorts = Filter(SavedNetworkPorts, func(port OsSerialPort) bool { - any := true - for _, p := range newPorts { - if p.Name == port.Name { - any = false - return any - } - } - return any - }) - - SavedNetworkPorts, err = pruneUnreachablePorts(SavedNetworkPorts) - if err != nil { - return nil, err - } - - SavedNetworkPorts = append(SavedNetworkPorts, newPorts...) - - return SavedNetworkPorts, nil -} - -func checkAvailability(ip string) bool { - timeout := time.Duration(1500 * time.Millisecond) - // Check if the port 80 is open - conn, err := net.DialTimeout("tcp", ip+":80", timeout) - if err != nil { - log.Println(err) - // Check if the port 22 is open - conn, err = net.DialTimeout("tcp", ip+":22", timeout) - if err != nil { - log.Println(err) - return false - } - conn.Close() - return true - } - conn.Close() - return true -} - -func pruneUnreachablePorts(ports []OsSerialPort) ([]OsSerialPort, error) { - times := 2 - - ports = Filter(ports, func(port OsSerialPort) bool { - any := false - for i := 0; i < times; i++ { - if checkAvailability(port.Name) { - any = true - } - } - return any - }) - - return ports, nil -} - -func getPorts() ([]OsSerialPort, error) { - resolver, err := bonjour.NewResolver(nil) - if err != nil { - log.Println("Failed to initialize resolver:", err.Error()) - return nil, err - } - - results := make(chan *bonjour.ServiceEntry) - - timeout := make(chan bool, 1) - go func(exitCh chan<- bool) { - time.Sleep(timeoutConst * time.Second) - exitCh <- true - close(results) - }(resolver.Exit) - - arrPorts := []OsSerialPort{} - go func(results chan *bonjour.ServiceEntry, exitCh chan<- bool) { - for e := range results { - log.Printf("%+v", e) - if e.AddrIPv4 != nil { - arrPorts = append(arrPorts, OsSerialPort{Name: e.AddrIPv4.String(), IDProduct: e.Instance, IDVendor: strings.Join(e.Text[:], " "), NetworkPort: true}) - } - } - timeout <- true - }(results, resolver.Exit) - - err = resolver.Browse("_arduino._tcp", "", results) - if err != nil { - log.Println("Failed to browse:", err.Error()) - return nil, err - } - // wait for some kind of timeout and return arrPorts - <-timeout - return arrPorts, nil -} - -// Filter returns a new slice containing all OsSerialPort in the slice that satisfy the predicate f. -func Filter(vs []OsSerialPort, f func(OsSerialPort) bool) []OsSerialPort { - var vsf []OsSerialPort - for _, v := range vs { - if f(v) { - vsf = append(vsf, v) - } - } - return vsf -} diff --git a/go.mod b/go.mod index 843a90cb8..1c4c2d33b 100644 --- a/go.mod +++ b/go.mod @@ -15,9 +15,7 @@ require ( github.com/googollee/go-socket.io v0.0.0-20181101151912-c8aeb1ed9b49 github.com/mattn/go-shellwords v1.0.12 github.com/mitchellh/go-homedir v1.1.0 - github.com/oleksandr/bonjour v0.0.0-20210301155756-30f43c61b915 github.com/pkg/errors v0.9.1 - github.com/sfreiberg/simplessh v0.0.0-20220719182921-185eafd40485 github.com/sirupsen/logrus v1.9.0 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/stretchr/testify v1.8.4 @@ -35,7 +33,6 @@ require ( github.com/cloudflare/circl v1.3.3 // indirect github.com/creack/goselect v0.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/davidmz/go-pageant v1.0.2 // indirect github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect @@ -62,17 +59,14 @@ require ( github.com/klauspost/compress v1.15.13 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/kr/binarydist v0.1.0 // indirect - github.com/kr/fs v0.1.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/leonelquinteros/gotext v1.4.0 // indirect github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/miekg/dns v1.1.35 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pkg/sftp v1.13.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect @@ -80,11 +74,11 @@ require ( github.com/ugorji/go v1.1.6 // indirect github.com/ulikunitz/xz v0.5.11 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.1 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 66c228397..208702ac4 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,6 @@ github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglD github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= -github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI= github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -102,8 +100,6 @@ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZX github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/kr/binarydist v0.1.0 h1:6kAoLA9FMMnNGSehX0s1PdjbEaACznAv/W219j2uvyo= github.com/kr/binarydist v0.1.0/go.mod h1:DY7S//GCoz1BCd0B0EVrinCKAZN3pXe+MDaIZbXQVgM= -github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -121,8 +117,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs= -github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -132,22 +126,16 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oleksandr/bonjour v0.0.0-20210301155756-30f43c61b915 h1:d291KOLbN1GthTPA1fLKyWdclX3k1ZP+CzYtun+a5Es= -github.com/oleksandr/bonjour v0.0.0-20210301155756-30f43c61b915/go.mod h1:MGuVJ1+5TX1SCoO2Sx0eAnjpdRytYla2uC1YIZfkC9c= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.4 h1:Lb0RYJCmgUcBgZosfoi9Y9sbl6+LJgOIgk/2Y4YjMFg= -github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sfreiberg/simplessh v0.0.0-20220719182921-185eafd40485 h1:ZMBZ2DKX1sScUSo9ZUwGI7jCMukslPNQNfZaw9vVyfY= -github.com/sfreiberg/simplessh v0.0.0-20220719182921-185eafd40485/go.mod h1:9qeq2P58+4+LyuncL3waJDG+giOfXgowfrRZZF9XdWk= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= @@ -186,41 +174,32 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -237,26 +216,22 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= diff --git a/home.html b/home.html index 61cade73d..30c241f22 100644 --- a/home.html +++ b/home.html @@ -32,11 +32,7 @@ let printMsg = msg; if (jsonMsg.Ports) { const validKeys = ['Name', 'SerialNumber', 'IsOpen', 'VendorID', 'ProductID']; - if (jsonMsg.Network) { - printMsg = "Network Ports:\n"+JSON.stringify(jsonMsg.Ports, validKeys, 2); - } else { - printMsg = "Serial Ports:\n"+JSON.stringify(jsonMsg.Ports, validKeys, 2); - } + printMsg = "Serial Ports:\n"+JSON.stringify(jsonMsg.Ports, validKeys, 2); } else if (Object.keys(jsonMsg).length !== 0) { printMsg = JSON.stringify(jsonMsg, undefined, 2); } diff --git a/hub.go b/hub.go index 70b1c9dd3..a4f966fbc 100755 --- a/hub.go +++ b/hub.go @@ -177,8 +177,7 @@ func checkCmd(m []byte) { // will catch send and sendnobuf and sendraw go spWrite(s) } else if strings.HasPrefix(sl, "list") { - go spList(false) - go spList(true) + go spList() } else if strings.HasPrefix(sl, "downloadtool") { go func() { args := strings.Split(s, " ") diff --git a/serial.go b/serial.go index e1270c7c6..86124faf3 100755 --- a/serial.go +++ b/serial.go @@ -51,9 +51,8 @@ type serialhub struct { // SpPortList is the serial port list type SpPortList struct { - Ports []SpPortItem - Network bool - Mu sync.Mutex `json:"-"` + Ports []SpPortItem + Mu sync.Mutex `json:"-"` } // SpPortItem is the serial port item @@ -66,7 +65,6 @@ type SpPortItem struct { Baud int BufferAlgorithm string Ver string - NetworkPort bool VendorID string ProductID string } @@ -74,9 +72,6 @@ type SpPortItem struct { // serialPorts contains the ports attached to the machine var serialPorts SpPortList -// networkPorts contains the ports on the network -var networkPorts SpPortList - var sh = serialhub{ //write: make(chan *serport, chan []byte), write: make(chan writeRequest), @@ -126,18 +121,12 @@ func write(wr writeRequest) { } // spList broadcasts a Json representation of the ports found -func spList(network bool) { +func spList() { var ls []byte var err error - if network { - networkPorts.Mu.Lock() - ls, err = json.MarshalIndent(&networkPorts, "", "\t") - networkPorts.Mu.Unlock() - } else { - serialPorts.Mu.Lock() - ls, err = json.MarshalIndent(&serialPorts, "", "\t") - serialPorts.Mu.Unlock() - } + serialPorts.Mu.Lock() + ls, err = json.MarshalIndent(&serialPorts, "", "\t") + serialPorts.Mu.Unlock() if err != nil { //log.Println(err) h.broadcastSys <- []byte("Error creating json on port list " + @@ -150,13 +139,8 @@ func spList(network bool) { // discoverLoop periodically update the list of ports found func discoverLoop() { serialPorts.Mu.Lock() - serialPorts.Network = false serialPorts.Ports = make([]SpPortItem, 0) serialPorts.Mu.Unlock() - networkPorts.Mu.Lock() - networkPorts.Network = true - networkPorts.Ports = make([]SpPortItem, 0) - networkPorts.Mu.Unlock() go func() { for { @@ -166,12 +150,6 @@ func discoverLoop() { time.Sleep(2 * time.Second) } }() - go func() { - for { - updateNetworkPortList() - time.Sleep(2 * time.Second) - } - }() } var serialEnumeratorLock sync.Mutex @@ -194,20 +172,6 @@ func updateSerialPortList() { serialPorts.Mu.Unlock() } -func updateNetworkPortList() { - ports, err := enumerateNetworkPorts() - if err != nil { - // TODO: report error? - - // Empty port list if they can not be detected - ports = []OsSerialPort{} - } - list := spListDual(ports) - networkPorts.Mu.Lock() - networkPorts.Ports = list - networkPorts.Mu.Unlock() -} - func spListDual(list []OsSerialPort) []SpPortItem { // we have a full clean list of ports now. iterate thru them // to append the open/close state, baud rates, etc to make @@ -224,7 +188,6 @@ func spListDual(list []OsSerialPort) []SpPortItem { Baud: 0, BufferAlgorithm: "", Ver: version, - NetworkPort: item.NetworkPort, VendorID: item.IDVendor, ProductID: item.IDProduct, } diff --git a/seriallist.go b/seriallist.go index 8e86ec08f..fd1046185 100755 --- a/seriallist.go +++ b/seriallist.go @@ -35,7 +35,6 @@ type OsSerialPort struct { IDProduct string IDVendor string ISerial string - NetworkPort bool } // enumerateSerialPorts will return the OS serial port diff --git a/serialport.go b/serialport.go index 41e2c1819..104311faf 100755 --- a/serialport.go +++ b/serialport.go @@ -233,7 +233,7 @@ func (p *serport) writerNoBuf() { h.broadcastSys <- []byte(msgstr) p.portIo.Close() updateSerialPortList() - spList(false) + spList() } // this method runs as its own thread because it's instantiated @@ -328,7 +328,7 @@ func spHandlerOpen(portname string, baud int, buftype string) { defer func() { sh.unregister <- p }() updateSerialPortList() - spList(false) + spList() // this is internally buffered thread to not send to serial port if blocked go p.writerBuffered() @@ -340,7 +340,7 @@ func spHandlerOpen(portname string, baud int, buftype string) { p.reader(buftype) updateSerialPortList() - spList(false) + spList() } func spHandlerClose(p *serport) { @@ -353,5 +353,5 @@ func spCloseReal(p *serport) { p.bufferwatcher.Close() p.portIo.Close() updateSerialPortList() - spList(false) + spList() } diff --git a/tests/test_ws.py b/tests/test_ws.py index 109f899be..c2623da56 100644 --- a/tests/test_ws.py +++ b/tests/test_ws.py @@ -33,7 +33,6 @@ def test_list(socketio, message): print (message) assert any("list" in i for i in message) assert any("Ports" in i for i in message) - assert any("Network" in i for i in message) # NOTE run the following tests with a board connected to the PC diff --git a/upload/README.md b/upload/README.md index a958e9352..57717cdf0 100644 --- a/upload/README.md +++ b/upload/README.md @@ -1,12 +1,10 @@ -use 'godoc cmd/github.com/arduino/arduino-create-agent/upload' for documentation on the github.com/arduino/arduino-create-agent/upload command - Package upload ===================== import "github.com/arduino/arduino-create-agent/upload" Package upload allows to upload sketches into a board connected to the -computer It can do it via serial port or via network +computer It can do it via serial port **Usage for a serial upload** @@ -19,17 +17,6 @@ err := upload.Serial("/dev/ttyACM0", commandline, upload.Extra{}, nil) note that the commandline contains the path of the sketch (sketch.hex) -**Usage for a network upload** - -Make sure that you have a compiled sketch somewhere on your disk - -```go - err := upload.Network("127.0.10.120", "arduino:avr:yun, "./sketch.hex", "", upload.Auth{}, nil) -``` - -The commandline can be empty or it can contain instructions (depends on the -board) - **Resolving commandlines** If you happen to have an unresolved commandline (full of {} parameters) you can @@ -73,13 +60,6 @@ func Kill() Kill stops any upload process as soon as possible -```go -func Network(port, board, file, commandline string, auth Auth, l Logger) error -``` - -Network performs a network upload - - ```go func Resolve(port, board, file, commandline string, extra Extra, t Locater) (string, error) ``` @@ -98,21 +78,11 @@ Types ----- -```go -type Auth struct { - Username string `json:"username"` - Password string `json:"password"` -} -``` -Auth contains username and password used for a network upload - - ```go type Extra struct { Use1200bpsTouch bool `json:"use_1200bps_touch"` WaitForUploadPort bool `json:"wait_for_upload_port"` Network bool `json:"network"` - Auth Auth `json:"auth"` } ``` Extra contains some options used during the upload @@ -133,5 +103,3 @@ type Logger interface { } ``` Logger is an interface implemented by most loggers (like logrus) - - diff --git a/upload/doc.go b/upload/doc.go deleted file mode 100644 index 0cf02682d..000000000 --- a/upload/doc.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2022 Arduino SA -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -// Package upload allows to upload sketches into a board connected to the computer -// It can do it via serial port or via network -// -// **Usage for a serial upload** -// -// Make sure that you have a compiled sketch somewhere on your disk -// -// ```go -// commandline = ``"/usr/bin/avrdude" "-C/usr/bin/avrdude.conf" -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./sketch.hex:i"`` -// err := upload.Serial("/dev/ttyACM0", commandline, upload.Extra{}, nil) -// ``` -// -// note that the commandline contains the path of the sketch (sketch.hex) -// -// **Usage for a network upload** -// -// Make sure that you have a compiled sketch somewhere on your disk -// -// ```go -// err := upload.Network("127.0.10.120", "arduino:avr:yun, "./sketch.hex", "", upload.Auth{}, nil) -// ``` -// -// The commandline can be empty or it can contain instructions (depends on the board) -// -// **Resolving commandlines** -// -// If you happen to have an unresolved commandline (full of {} parameters) you can resolve it -// -// ```go -// t := tools.Tools{} -// commandline = upload.Resolve("/dev/ttyACM0", "arduino:avr:leonardo", "./sketch.hex", commandline, upload.Extra{}, t) -// ``` -// -// 't' must implement the locater interface (the Tools package does!) -// -// **Logging** -// If you're interested in the output of the commands, you can implement the logger interface. Here's an example: -// -// ```go -// logger := logrus.New() -// logger.Level = logrus.DebugLevel -// upload.Serial("/dev/ttyACM0", commandline, upload.Extra{}, logger) -// ``` -package upload diff --git a/upload/upload.go b/upload/upload.go index 44d138aa3..0a3b0bace 100644 --- a/upload/upload.go +++ b/upload/upload.go @@ -17,46 +17,27 @@ package upload import ( "bufio" - "bytes" - "fmt" - "io" - "log" - "mime/multipart" - "net/http" - "os" "os/exec" "path/filepath" "regexp" "runtime" - "strconv" "strings" "github.com/arduino/arduino-cli/arduino/serialutils" "github.com/arduino/arduino-create-agent/utilities" shellwords "github.com/mattn/go-shellwords" "github.com/pkg/errors" - "github.com/sfreiberg/simplessh" "go.bug.st/serial/enumerator" ) // Busy tells wether the programmer is doing something var Busy = false -// Auth contains username and password used for a network upload -type Auth struct { - Username string `json:"username"` - Password string `json:"password"` - PrivateKey string `json:"private_key"` - Port int `json:"port"` -} - // Extra contains some options used during the upload type Extra struct { Use1200bpsTouch bool `json:"use_1200bps_touch"` WaitForUploadPort bool `json:"wait_for_upload_port"` Network bool `json:"network"` - Auth Auth `json:"auth"` - SSH bool `json:"ssh,omitempty"` } // PartiallyResolve replaces some symbols in the commandline with the appropriate values @@ -64,7 +45,6 @@ type Extra struct { func PartiallyResolve(board, file, platformPath, commandline string, extra Extra, t Locater) (string, error) { commandline = strings.Replace(commandline, "{build.path}", filepath.ToSlash(filepath.Dir(file)), -1) commandline = strings.Replace(commandline, "{build.project_name}", strings.TrimSuffix(filepath.Base(file), filepath.Ext(filepath.Base(file))), -1) - commandline = strings.Replace(commandline, "{network.password}", extra.Auth.Password, -1) commandline = strings.Replace(commandline, "{runtime.platform.path}", filepath.ToSlash(platformPath), -1) // search for runtime variables and replace with values from Locater @@ -99,31 +79,6 @@ func fixupPort(port, commandline string) string { return commandline } -// Network performs a network upload -func Network(port, board string, files []string, commandline string, auth Auth, l Logger, SSH bool) error { - Busy = true - - // Defaults - if auth.Username == "" { - auth.Username = "root" - } - if auth.Password == "" { - auth.Password = "arduino" - } - - commandline = fixupPort(port, commandline) - - // try with ssh - err := ssh(port, files, commandline, auth, l, SSH) - if err != nil && !SSH { - // fallback on form - err = form(port, board, files[0], auth, l) - } - - Busy = false - return err -} - // Serial performs a serial upload func Serial(port, commandline string, extra Extra, l Logger) error { Busy = true @@ -242,161 +197,3 @@ func program(binary string, args []string, l Logger) error { } return nil } - -func form(port, board, file string, auth Auth, l Logger) error { - // Prepare a form that you will submit to that URL. - _url := "http://" + port + "/data/upload_sketch_silent" - var b bytes.Buffer - w := multipart.NewWriter(&b) - - // Add your image file - file = strings.Trim(file, "\n") - f, err := os.Open(file) - if err != nil { - return errors.Wrapf(err, "Open file %s", file) - } - fw, err := w.CreateFormFile("sketch_hex", file) - if err != nil { - return errors.Wrapf(err, "Create form file") - } - if _, err = io.Copy(fw, f); err != nil { - return errors.Wrapf(err, "Copy form file") - } - - // Add the other fields - board = strings.Replace(board, ":", "_", -1) - if fw, err = w.CreateFormField("board"); err != nil { - return errors.Wrapf(err, "Create board field") - } - if _, err = fw.Write([]byte(board)); err != nil { - return errors.Wrapf(err, "") - } - - // Don't forget to close the multipart writer. - // If you don't close it, your request will be missing the terminating boundary. - w.Close() - - // Now that you have a form, you can submit it to your handler. - req, err := http.NewRequest("POST", _url, &b) - if err != nil { - return errors.Wrapf(err, "Create POST req") - } - - // Don't forget to set the content type, this will contain the boundary. - req.Header.Set("Content-Type", w.FormDataContentType()) - if auth.Username != "" { - req.SetBasicAuth(auth.Username, auth.Password) - } - - info(l, "Network upload on ", port) - - // Submit the request - client := &http.Client{} - res, err := client.Do(req) - if err != nil { - log.Println("Error during post request") - return errors.Wrapf(err, "") - } - - // Check the response - if res.StatusCode != http.StatusOK { - body, _ := io.ReadAll(res.Body) - return errors.New("Request error:" + string(body)) - } - return nil -} - -func ssh(port string, files []string, commandline string, auth Auth, l Logger, SSH bool) error { - debug(l, "Connect via ssh ", files, commandline) - - if auth.Port == 0 { - auth.Port = 22 - } - - // Connect via ssh - var client *simplessh.Client - var err error - if auth.PrivateKey != "" { - client, err = simplessh.ConnectWithKeyFile(port+":"+strconv.Itoa(auth.Port), auth.Username, auth.PrivateKey) - } else { - client, err = simplessh.ConnectWithPassword(port+":"+strconv.Itoa(auth.Port), auth.Username, auth.Password) - } - - if err != nil { - return errors.Wrapf(err, "Connect via ssh") - } - defer client.Close() - - // Copy the sketch - for _, file := range files { - fileName := "/tmp/sketch" + filepath.Ext(file) - if SSH { - // don't rename files - fileName = "/tmp/" + filepath.Base(file) - } - err = scp(client, file, fileName) - debug(l, "Copy "+file+" to "+fileName+" ", err) - if err != nil { - return errors.Wrapf(err, "Copy sketch") - } - } - - // very special case for Yun (remove once AVR boards.txt is fixed) - if commandline == "" { - commandline = "merge-sketch-with-bootloader.lua /tmp/sketch.hex && /usr/bin/run-avrdude /tmp/sketch.hex" - } - - // Execute commandline - output, err := client.Exec(commandline) - info(l, string(output)) - debug(l, "Execute commandline ", commandline, string(output), err) - if err != nil { - return errors.Wrapf(err, "Execute commandline") - } - return nil -} - -// scp uploads sourceFile to remote machine like native scp console app. -func scp(client *simplessh.Client, sourceFile, targetFile string) error { - // open ssh session - session, err := client.SSHClient.NewSession() - if err != nil { - return errors.Wrapf(err, "open ssh session") - } - defer session.Close() - - // open file - src, err := os.Open(sourceFile) - if err != nil { - return errors.Wrapf(err, "open file %s", sourceFile) - } - - // stat file - srcStat, err := src.Stat() - if err != nil { - return errors.Wrapf(err, "stat file %s", sourceFile) - } - - // Copy over ssh - go func() { - w, _ := session.StdinPipe() - - fmt.Fprintln(w, "C0644", srcStat.Size(), filepath.Base(targetFile)) - - if srcStat.Size() > 0 { - io.Copy(w, src) - fmt.Fprint(w, "\x00") - w.Close() - } else { - fmt.Fprint(w, "\x00") - w.Close() - } - - }() - - if err := session.Run("scp -t " + targetFile); err != nil { - return errors.Wrapf(err, "Execute %s", "scp -t "+targetFile) - } - - return nil -} diff --git a/upload/upload_test.go b/upload/upload_test.go index ff38fe025..7f5f46418 100644 --- a/upload/upload_test.go +++ b/upload/upload_test.go @@ -56,42 +56,6 @@ func TestSerial(t *testing.T) { } } -var TestNetworkData = []struct { - Name string - Port string - Board string - Files []string - Commandline string - Extra upload.Extra -}{ - { - "yun", - "", - "", - []string{"filename"}, - "", - upload.Extra{ - Use1200bpsTouch: true, - WaitForUploadPort: true, - Network: true, - Auth: upload.Auth{}, - }, - }, -} - -func TestNetwork(t *testing.T) { - logger := logrus.New() - logger.Level = logrus.DebugLevel - - home, _ := homedir.Dir() - - for _, test := range TestNetworkData { - commandline := strings.Replace(test.Commandline, "$HOME", home, -1) - err := upload.Network(test.Port, test.Board, test.Files, commandline, test.Extra.Auth, logger, test.Extra.SSH) - log.Println(err) - } -} - var TestResolveData = []struct { Board string File string