mirror of
https://github.com/FlipsideCrypto/convox.git
synced 2026-02-06 10:56:56 +00:00
cli: terraform rack management (#79)
* vendor * local rack management via terraform * update mocks * update tests for new local rack management * clean up rack matcher and add more tests * switch to rack after install, add more tests
This commit is contained in:
parent
17cad1eae0
commit
a7f20d9f29
6
go.mod
6
go.mod
@ -19,7 +19,7 @@ require (
|
||||
github.com/convox/hid v0.0.0-20180912192857-c67381b7ffff
|
||||
github.com/convox/logger v0.0.0-20180522214415-e39179955b52
|
||||
github.com/convox/stdapi v0.0.0-20190708203955-b81b71b6a680
|
||||
github.com/convox/stdcli v0.0.0-20190326115454-b78bee159e98
|
||||
github.com/convox/stdcli v0.0.0-20200122204822-238a68a930fd
|
||||
github.com/convox/stdsdk v0.0.0-20190422120437-3e80a397e377
|
||||
github.com/convox/u2f v0.0.0-20180912192910-a73404142726
|
||||
github.com/convox/version v0.0.0-20160822184233-ffefa0d565d2
|
||||
@ -50,9 +50,9 @@ require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/vektra/mockery v0.0.0-20181123154057-e78b021dcbb5
|
||||
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 // indirect
|
||||
golang.org/x/sys v0.0.0-20191104094858-e8c54fb511f6 // indirect
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 // indirect
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
|
||||
google.golang.org/api v0.9.0
|
||||
gopkg.in/inf.v0 v0.9.0 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@ -59,6 +59,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/adrg/xdg v0.2.1 h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=
|
||||
github.com/adrg/xdg v0.2.1/go.mod h1:ZuOshBmzV4Ta+s23hdfFZnBsdzmoR3US0d7ErpqSbTQ=
|
||||
github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
@ -91,8 +93,8 @@ github.com/convox/logger v0.0.0-20180522214415-e39179955b52 h1:HTaloo6by+4NE1A1m
|
||||
github.com/convox/logger v0.0.0-20180522214415-e39179955b52/go.mod h1:IcbSD+Pq+bQV2z/otiMCHLAYBrDR/jPFopFatrWjlMM=
|
||||
github.com/convox/stdapi v0.0.0-20190708203955-b81b71b6a680 h1:IRgaDO4+YanUYcvBlXkzJrgwFh/3BcQOYoI5gEUz2wQ=
|
||||
github.com/convox/stdapi v0.0.0-20190708203955-b81b71b6a680/go.mod h1:NkUGoKf5tAaHq7MW02AF9mSXSIHCZJ0ZG8+NqRI5t38=
|
||||
github.com/convox/stdcli v0.0.0-20190326115454-b78bee159e98 h1:jSUPA5xGpERhDUevVwj8YPXhIbKq+YJPXpF8U9M4p1o=
|
||||
github.com/convox/stdcli v0.0.0-20190326115454-b78bee159e98/go.mod h1:D+mhXWLSLHQ+I2zZzYfrSzONMlE6FnPFw9hM4oDcN8Y=
|
||||
github.com/convox/stdcli v0.0.0-20200122204822-238a68a930fd h1:xU0A7L467EvnyNrtlSiLdVdoFzcVmF7gqTC/z5yjU8k=
|
||||
github.com/convox/stdcli v0.0.0-20200122204822-238a68a930fd/go.mod h1:kLknwv4KTN9f9fZ2DDvG/L9ndXkcijaexIZ0enACvSc=
|
||||
github.com/convox/stdsdk v0.0.0-20190422120437-3e80a397e377 h1:PuSJ72MD0mYsMCTvTQ1YydIbQUWtEykNHyweI/vA0PY=
|
||||
github.com/convox/stdsdk v0.0.0-20190422120437-3e80a397e377/go.mod h1:y1vtmkDKBkWSQ6e2gPXAyz1NCuWZ2x3vrP/SFeDDNco=
|
||||
github.com/convox/u2f v0.0.0-20180912192910-a73404142726 h1:FY8dxqTRVj4lRmNoAkOeYxSnxZ40s64P/yxyVf8NBlo=
|
||||
@ -557,6 +559,8 @@ github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzu
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
|
||||
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
@ -604,8 +608,8 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4=
|
||||
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHawoXIhKyTGfvvjFAiiAk=
|
||||
@ -688,8 +692,8 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ=
|
||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191104094858-e8c54fb511f6 h1:ZJUmhYTp8GbGC0ViZRc2U+MIYQ8xx9MscsdXnclfIhw=
|
||||
golang.org/x/sys v0.0.0-20191104094858-e8c54fb511f6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@ -64,17 +64,3 @@ func (_m *MockInterface) Status(ns string, name string) (string, string, error)
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// Wait provides a mock function with given fields: ns, name
|
||||
func (_m *MockInterface) Wait(ns string, name string) error {
|
||||
ret := _m.Called(ns, name)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(ns, name)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@ -14,6 +15,7 @@ import (
|
||||
"github.com/convox/convox/pkg/cli"
|
||||
"github.com/convox/convox/pkg/common"
|
||||
mocksdk "github.com/convox/convox/pkg/mock/sdk"
|
||||
mockstdcli "github.com/convox/convox/pkg/mock/stdcli"
|
||||
"github.com/convox/convox/pkg/structs"
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -95,6 +97,26 @@ func testExecuteContext(ctx context.Context, e *cli.Engine, cmd string, stdin io
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func testLocalRack(e *cli.Engine, name, provider, api string) error {
|
||||
dir := filepath.Join(e.Settings, "racks", name)
|
||||
|
||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "main.tf"), []byte{}, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := []byte(fmt.Sprintf(`{"api":{"value":%q},"provider":{"value":%q}}`, api, provider))
|
||||
|
||||
me := &mockstdcli.Executor{}
|
||||
me.On("Execute", "terraform", "output", "-json").Return(data, nil)
|
||||
e.Executor = me
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testLogs(logs []string) io.ReadCloser {
|
||||
return ioutil.NopCloser(strings.NewReader(fmt.Sprintf("%s\n", strings.Join(logs, "\n"))))
|
||||
}
|
||||
|
||||
@ -41,25 +41,32 @@ func (e *Engine) currentClient(c *stdcli.Context) sdk.Interface {
|
||||
return e.Client
|
||||
}
|
||||
|
||||
// url, err := currentEndpoint(c)
|
||||
// if err != nil {
|
||||
// c.Fail(err)
|
||||
// }
|
||||
|
||||
host, err := currentHost(c)
|
||||
if err != nil {
|
||||
c.Fail(err)
|
||||
}
|
||||
|
||||
r := currentRack(c, host)
|
||||
|
||||
endpoint, err := currentEndpoint(c, r)
|
||||
r, err := matchRack(c, currentRack(c, host))
|
||||
if err != nil {
|
||||
c.Fail(err)
|
||||
}
|
||||
|
||||
sc, err := sdk.New(endpoint)
|
||||
// if r == nil {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
sc, err := sdk.New(r.Url)
|
||||
if err != nil {
|
||||
c.Fail(err)
|
||||
}
|
||||
|
||||
sc.Authenticator = authenticator(c)
|
||||
sc.Rack = r
|
||||
sc.Rack = r.Name
|
||||
sc.Session = currentSession(c)
|
||||
|
||||
return sc
|
||||
|
||||
@ -318,7 +318,7 @@ func fxSystemLocal() *structs.System {
|
||||
Name: "convox",
|
||||
Provider: "local",
|
||||
Status: "running",
|
||||
Version: "dev",
|
||||
Version: "dev1",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,8 +6,11 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
@ -22,8 +25,11 @@ import (
|
||||
)
|
||||
|
||||
type rack struct {
|
||||
Name string
|
||||
Status string
|
||||
Name string
|
||||
Provider string
|
||||
Remote bool
|
||||
Status string
|
||||
Url string
|
||||
}
|
||||
|
||||
func app(c *stdcli.Context) string {
|
||||
@ -65,52 +71,26 @@ func currentPassword(c *stdcli.Context, host string) (string, error) {
|
||||
return c.SettingReadKey("auth", host)
|
||||
}
|
||||
|
||||
func currentEndpoint(c *stdcli.Context, rack_ string) (string, error) {
|
||||
func currentEndpoint(c *stdcli.Context) (string, error) {
|
||||
if e := os.Getenv("RACK_URL"); e != "" {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rack_, "local/") {
|
||||
return fmt.Sprintf("https://api.%s", strings.SplitN(rack_, "/", 2)[1]), nil
|
||||
}
|
||||
|
||||
host, err := currentHost(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if host == "" {
|
||||
if !localRackRunning(c) {
|
||||
return "", fmt.Errorf("no racks found, try `convox login`")
|
||||
}
|
||||
|
||||
var r *rack
|
||||
|
||||
if cr := currentRack(c, ""); cr != "" {
|
||||
r, err = matchRack(c, cr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
r, err = matchRack(c, "local/")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
return "", fmt.Errorf("no racks found, try `convox login`")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("https://rack.%s", strings.SplitN(r.Name, "/", 2)[1]), nil
|
||||
if pw := os.Getenv("CONVOX_PASSWORD"); host != "" && pw != "" {
|
||||
return fmt.Sprintf("https://convox:%s@%s", url.QueryEscape(pw), host), nil
|
||||
}
|
||||
|
||||
pw, err := currentPassword(c, host)
|
||||
r, err := matchRack(c, currentRack(c, host))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("https://convox:%s@%s", url.QueryEscape(pw), host), nil
|
||||
return r.Url, nil
|
||||
}
|
||||
|
||||
func currentRack(c *stdcli.Context, host string) string {
|
||||
@ -159,7 +139,7 @@ func generateTempKey() (string, error) {
|
||||
}
|
||||
|
||||
func hostRacks(c *stdcli.Context) map[string]string {
|
||||
data, err := c.SettingRead("racks")
|
||||
data, err := c.SettingRead("switch")
|
||||
if err != nil {
|
||||
return map[string]string{}
|
||||
}
|
||||
@ -183,26 +163,77 @@ func localRackRunning(c *stdcli.Context) bool {
|
||||
}
|
||||
|
||||
func localRacks(c *stdcli.Context) ([]rack, error) {
|
||||
if os.Getenv("CONVOX_LOCAL") == "disable" {
|
||||
dir, err := c.SettingDirectory("racks")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
return []rack{}, nil
|
||||
}
|
||||
|
||||
subs, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
racks := []rack{}
|
||||
|
||||
data, err := c.Execute("kubectl", "get", "ns", "--selector=system=convox,type=rack", "--output=name")
|
||||
if err == nil {
|
||||
nsrs := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Chdir(wd)
|
||||
|
||||
for _, nsr := range nsrs {
|
||||
if strings.HasPrefix(nsr, "namespace/") {
|
||||
if name, err := c.Execute("kubectl", "get", nsr, "-o", "jsonpath={.metadata.labels.rack}"); err == nil {
|
||||
racks = append(racks, rack{
|
||||
Name: fmt.Sprintf("local/%s", strings.TrimSpace(string(name))),
|
||||
Status: "running",
|
||||
})
|
||||
}
|
||||
}
|
||||
for _, sub := range subs {
|
||||
if !sub.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
tf := filepath.Join(dir, sub.Name(), "main.tf")
|
||||
|
||||
if _, err := os.Stat(tf); os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
os.Chdir(filepath.Dir(tf))
|
||||
|
||||
data, err := c.Execute("terraform", "output", "-json")
|
||||
if err != nil {
|
||||
fmt.Printf("err: %+v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
var output map[string]struct {
|
||||
Sensitive bool
|
||||
Type string
|
||||
Value string
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &output); err != nil {
|
||||
fmt.Printf("err: %+v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
api := ""
|
||||
provider := "unknown"
|
||||
status := "unknown"
|
||||
|
||||
if o, ok := output["api"]; ok {
|
||||
api = o.Value
|
||||
status = "running"
|
||||
}
|
||||
|
||||
if o, ok := output["provider"]; ok {
|
||||
provider = o.Value
|
||||
}
|
||||
|
||||
racks = append(racks, rack{
|
||||
Name: sub.Name(),
|
||||
Provider: strings.TrimSpace(string(provider)),
|
||||
Status: status,
|
||||
Url: strings.TrimSpace(string(api)),
|
||||
})
|
||||
}
|
||||
|
||||
return racks, nil
|
||||
@ -226,27 +257,30 @@ func matchRack(c *stdcli.Context, name string) (*rack, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(matches) > 1 {
|
||||
if name == "" {
|
||||
switch len(matches) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("no racks found")
|
||||
case 1:
|
||||
return &matches[0], nil
|
||||
default:
|
||||
return nil, fmt.Errorf("multiple racks detected, use `convox switch` to select one")
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matches) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("could not find rack: %s", name)
|
||||
case 1:
|
||||
return &matches[0], nil
|
||||
default:
|
||||
return nil, fmt.Errorf("ambiguous rack name: %s", name)
|
||||
}
|
||||
|
||||
if len(matches) == 1 {
|
||||
return &matches[0], nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("could not find rack: %s", name)
|
||||
}
|
||||
|
||||
func racks(c *stdcli.Context) ([]rack, error) {
|
||||
rs := []rack{}
|
||||
|
||||
rrs, err := remoteRacks(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rs = append(rs, rrs...)
|
||||
|
||||
lrs, err := localRacks(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -254,40 +288,41 @@ func racks(c *stdcli.Context) ([]rack, error) {
|
||||
|
||||
rs = append(rs, lrs...)
|
||||
|
||||
rrs, err := remoteRacks(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rs = append(rs, rrs...)
|
||||
|
||||
sort.Slice(rs, func(i, j int) bool {
|
||||
return rs[i].Name < rs[j].Name
|
||||
if !rs[i].Remote && rs[j].Remote {
|
||||
return true
|
||||
} else {
|
||||
return rs[i].Name < rs[j].Name
|
||||
}
|
||||
})
|
||||
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func remoteRacks(c *stdcli.Context) ([]rack, error) {
|
||||
h, err := currentHost(c)
|
||||
host, err := currentHost(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if h == "" {
|
||||
if host == "" {
|
||||
return []rack{}, nil
|
||||
}
|
||||
|
||||
racks := []rack{}
|
||||
|
||||
var rs []struct {
|
||||
Name string
|
||||
Organization struct {
|
||||
Name string
|
||||
}
|
||||
Status string
|
||||
}
|
||||
|
||||
// override local rack to get remote rack list
|
||||
endpoint, err := currentEndpoint(c, "")
|
||||
pw, err := currentPassword(c, host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p, err := sdk.New(endpoint)
|
||||
remote := fmt.Sprintf("https://convox:%s@%s", url.QueryEscape(pw), host)
|
||||
|
||||
p, err := sdk.New(remote)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -295,28 +330,176 @@ func remoteRacks(c *stdcli.Context) ([]rack, error) {
|
||||
p.Authenticator = authenticator(c)
|
||||
p.Session = currentSession(c)
|
||||
|
||||
var rs []struct {
|
||||
Name string
|
||||
Organization struct {
|
||||
Name string
|
||||
}
|
||||
Provider string
|
||||
Status string
|
||||
}
|
||||
|
||||
if err := p.Get("/racks", stdsdk.RequestOptions{}, &rs); err != nil {
|
||||
if _, ok := err.(AuthenticationError); ok {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if rs != nil {
|
||||
for _, r := range rs {
|
||||
racks = append(racks, rack{
|
||||
Name: fmt.Sprintf("%s/%s", r.Organization.Name, r.Name),
|
||||
Status: r.Status,
|
||||
})
|
||||
}
|
||||
racks := []rack{}
|
||||
|
||||
for _, r := range rs {
|
||||
racks = append(racks, rack{
|
||||
Name: fmt.Sprintf("%s/%s", r.Organization.Name, r.Name),
|
||||
Provider: r.Provider,
|
||||
Remote: true,
|
||||
Status: r.Status,
|
||||
Url: remote,
|
||||
})
|
||||
}
|
||||
|
||||
return racks, nil
|
||||
}
|
||||
|
||||
func requireEnv(vars ...string) (map[string]string, error) {
|
||||
env := map[string]string{}
|
||||
missing := []string{}
|
||||
|
||||
for _, k := range vars {
|
||||
if v := os.Getenv(k); v != "" {
|
||||
env[k] = v
|
||||
} else {
|
||||
missing = append(missing, k)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return nil, fmt.Errorf("required env: %s", strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
func switchRack(c *stdcli.Context, name string) error {
|
||||
rs := hostRacks(c)
|
||||
|
||||
host, err := currentHost(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rs[host] = name
|
||||
|
||||
data, err := json.MarshalIndent(rs, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.SettingWrite("switch", string(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tag(name, value string) string {
|
||||
return fmt.Sprintf("<%s>%s</%s>", name, value, name)
|
||||
}
|
||||
|
||||
func terraform(c *stdcli.Context, dir string, env map[string]string, args ...string) error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Chdir(wd)
|
||||
|
||||
if err := os.Chdir(dir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
signal.Ignore(os.Interrupt)
|
||||
defer signal.Reset(os.Interrupt)
|
||||
|
||||
if err := c.Terminal("terraform", args...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func terraformEnv(provider string) (map[string]string, error) {
|
||||
switch provider {
|
||||
case "aws":
|
||||
return requireEnv("AWS_DEFAULT_REGION", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY")
|
||||
case "azure":
|
||||
return requireEnv("ARM_CLIENT_ID", "ARM_CLIENT_SECRET", "ARM_SUBSCRIPTION_ID", "ARM_TENANT_ID")
|
||||
case "gcp":
|
||||
return requireEnv("GOOGLE_CREDENTIALS", "GOOGLE_PROJECT", "GOOGLE_REGION")
|
||||
default:
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func terraformVars(provider string) (map[string]string, error) {
|
||||
switch provider {
|
||||
case "do":
|
||||
env, err := requireEnv("DIGITALOCEAN_ACCESS_ID", "DIGITALOCEAN_SECRET_KEY", "DIGITALOCEAN_TOKEN")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vars := map[string]string{
|
||||
"access_id": env["DIGITALOCEAN_ACCESS_ID"],
|
||||
"secret_key": env["DIGITALOCEAN_SECRET_KEY"],
|
||||
"token": env["DIGITALOCEAN_TOKEN"],
|
||||
}
|
||||
return vars, nil
|
||||
default:
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func terraformWriteTemplate(filename string, params map[string]interface{}) error {
|
||||
if source := os.Getenv("CONVOX_TERRAFORM_SOURCE"); source != "" {
|
||||
params["Source"] = fmt.Sprintf(source, params["Provider"])
|
||||
} else {
|
||||
params["Source"] = fmt.Sprintf("github.com/convox/convox//terraform/system/%s", params["Provider"])
|
||||
}
|
||||
|
||||
t, err := template.New("main").Parse(`
|
||||
module "system" {
|
||||
source = "{{.Source}}"
|
||||
|
||||
name = "{{.Name}}"
|
||||
release = "{{.Release}}"
|
||||
{{- range $k, $v := .Vars }}
|
||||
{{$k}} = "{{$v}}"
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
output "api" {
|
||||
value = module.system.api
|
||||
}
|
||||
|
||||
output "provider" {
|
||||
value = "{{.Provider}}"
|
||||
}`,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fd, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
if err := t.Execute(fd, params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func waitForResourceDeleted(rack sdk.Interface, c *stdcli.Context, resource string) error {
|
||||
s, err := rack.SystemGet()
|
||||
if err != nil {
|
||||
|
||||
186
pkg/cli/rack.go
186
pkg/cli/rack.go
@ -3,6 +3,8 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -11,8 +13,6 @@ import (
|
||||
"github.com/convox/convox/pkg/structs"
|
||||
"github.com/convox/convox/sdk"
|
||||
"github.com/convox/stdcli"
|
||||
|
||||
cv "github.com/convox/version"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -21,6 +21,11 @@ func init() {
|
||||
Validate: stdcli.Args(0),
|
||||
})
|
||||
|
||||
registerWithoutProvider("rack install", "install a new rack", RackInstall, stdcli.CommandOptions{
|
||||
Usage: "<provider> <name>",
|
||||
Validate: stdcli.Args(2),
|
||||
})
|
||||
|
||||
register("rack logs", "get logs for the rack", RackLogs, stdcli.CommandOptions{
|
||||
Flags: append(stdcli.OptionFlags(structs.LogsOptions{}), flagNoFollow, flagRack),
|
||||
Validate: stdcli.Args(0),
|
||||
@ -56,9 +61,14 @@ func init() {
|
||||
Validate: stdcli.Args(0),
|
||||
})
|
||||
|
||||
register("rack update", "update the rack", RackUpdate, stdcli.CommandOptions{
|
||||
Flags: []stdcli.Flag{flagRack},
|
||||
Validate: stdcli.ArgsMax(1),
|
||||
registerWithoutProvider("rack uninstall", "uninstall a rack", RackUninstall, stdcli.CommandOptions{
|
||||
Usage: "<name>",
|
||||
Validate: stdcli.Args(1),
|
||||
})
|
||||
|
||||
registerWithoutProvider("rack update", "update a rack", RackUpdate, stdcli.CommandOptions{
|
||||
Usage: "<name>",
|
||||
Validate: stdcli.Args(1),
|
||||
})
|
||||
}
|
||||
|
||||
@ -91,6 +101,61 @@ func Rack(rack sdk.Interface, c *stdcli.Context) error {
|
||||
return i.Print()
|
||||
}
|
||||
|
||||
func RackInstall(rack sdk.Interface, c *stdcli.Context) error {
|
||||
provider := c.Arg(0)
|
||||
name := c.Arg(1)
|
||||
|
||||
env, err := terraformEnv(provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vars, err := terraformVars(provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dir, err := c.SettingDirectory(fmt.Sprintf("racks/%s", name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tf := filepath.Join(dir, "main.tf")
|
||||
|
||||
if _, err := os.Stat(tf); !os.IsNotExist(err) {
|
||||
return fmt.Errorf("rack name in use: %s", name)
|
||||
}
|
||||
|
||||
params := map[string]interface{}{
|
||||
"Name": name,
|
||||
"Provider": provider,
|
||||
"Release": "",
|
||||
"Vars": vars,
|
||||
}
|
||||
|
||||
if err := terraformWriteTemplate(tf, params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := terraform(c, dir, env, "init"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := terraform(c, dir, env, "apply", "-auto-approve"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := switchRack(c, name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RackLogs(rack sdk.Interface, c *stdcli.Context) error {
|
||||
var opts structs.LogsOptions
|
||||
|
||||
@ -253,39 +318,98 @@ func RackScale(rack sdk.Interface, c *stdcli.Context) error {
|
||||
return i.Print()
|
||||
}
|
||||
|
||||
func RackUpdate(rack sdk.Interface, c *stdcli.Context) error {
|
||||
target := c.Arg(0)
|
||||
func RackUninstall(rack sdk.Interface, c *stdcli.Context) error {
|
||||
name := c.Arg(0)
|
||||
|
||||
// if no version specified, find the next version
|
||||
if target == "" {
|
||||
s, err := rack.SystemGet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.Version == "dev" {
|
||||
target = "dev"
|
||||
} else {
|
||||
v, err := cv.Next(s.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
target = v
|
||||
}
|
||||
}
|
||||
|
||||
c.Startf("Updating to <release>%s</release>", target)
|
||||
|
||||
if err := rack.SystemUpdate(structs.SystemUpdateOptions{Version: options.String(target)}); err != nil {
|
||||
r, err := matchRack(c, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Writef("\n")
|
||||
if r.Remote {
|
||||
return rackUninstallRemote(c, name)
|
||||
}
|
||||
|
||||
if err := common.WaitForRackWithLogs(rack, c); err != nil {
|
||||
env, err := terraformEnv(r.Provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dir, err := c.SettingDirectory(fmt.Sprintf("racks/%s", name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := terraform(c, dir, env, "init", "-upgrade"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := terraform(c, dir, env, "destroy", "-auto-approve"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RackUpdate(rack sdk.Interface, c *stdcli.Context) error {
|
||||
name := c.Arg(0)
|
||||
|
||||
r, err := matchRack(c, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.Remote {
|
||||
return rackUpdateRemote(c, name)
|
||||
}
|
||||
|
||||
env, err := terraformEnv(r.Provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vars, err := terraformVars(r.Provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dir, err := c.SettingDirectory(fmt.Sprintf("racks/%s", name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tf := filepath.Join(dir, "main.tf")
|
||||
|
||||
params := map[string]interface{}{
|
||||
"Name": name,
|
||||
"Provider": r.Provider,
|
||||
"Release": "",
|
||||
"Vars": vars,
|
||||
}
|
||||
|
||||
if err := terraformWriteTemplate(tf, params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := terraform(c, dir, env, "init", "-upgrade"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := terraform(c, dir, env, "apply", "-auto-approve"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.OK()
|
||||
}
|
||||
|
||||
func rackUninstallRemote(c *stdcli.Context, name string) error {
|
||||
return fmt.Errorf("uninstalling remote racks not yet supported")
|
||||
}
|
||||
|
||||
func rackUpdateRemote(c *stdcli.Context, name string) error {
|
||||
return fmt.Errorf("updating remote racks not yet supported")
|
||||
}
|
||||
|
||||
@ -2,11 +2,16 @@ package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/convox/convox/pkg/cli"
|
||||
mocksdk "github.com/convox/convox/pkg/mock/sdk"
|
||||
mockstdcli "github.com/convox/convox/pkg/mock/stdcli"
|
||||
"github.com/convox/convox/pkg/options"
|
||||
"github.com/convox/convox/pkg/structs"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@ -44,6 +49,45 @@ func TestRackError(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackInstall(t *testing.T) {
|
||||
testClientWait(t, 50*time.Millisecond, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
me := &mockstdcli.Executor{}
|
||||
me.On("Terminal", "terraform", "init").Return(nil)
|
||||
me.On("Terminal", "terraform", "apply", "-auto-approve").Return(nil)
|
||||
e.Executor = me
|
||||
|
||||
res, err := testExecute(e, "rack install local dev1", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{""})
|
||||
|
||||
dir := filepath.Join(e.Settings, "racks", "dev1")
|
||||
tf := filepath.Join(dir, "main.tf")
|
||||
|
||||
_, err = os.Stat(dir)
|
||||
require.NoError(t, err)
|
||||
_, err = os.Stat(tf)
|
||||
require.NoError(t, err)
|
||||
|
||||
tfdata, err := ioutil.ReadFile(tf)
|
||||
require.NoError(t, err)
|
||||
|
||||
testdata, err := ioutil.ReadFile("testdata/terraform.local.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, strings.Trim(string(tfdata), "\n"), strings.Trim(string(testdata), "\n"))
|
||||
|
||||
res, err = testExecute(e, "switch", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{"dev1"})
|
||||
|
||||
me.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackInternal(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
i.On("SystemGet").Return(fxSystemInternal(), nil)
|
||||
@ -326,34 +370,87 @@ func TestRackScaleUpdateError(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackUninstall(t *testing.T) {
|
||||
testClientWait(t, 50*time.Millisecond, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
me := e.Executor.(*mockstdcli.Executor)
|
||||
me.On("Terminal", "terraform", "init", "-upgrade").Return(nil)
|
||||
me.On("Terminal", "terraform", "destroy", "-auto-approve").Return(nil)
|
||||
|
||||
res, err := testExecute(e, "rack uninstall dev1", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{""})
|
||||
|
||||
dir := filepath.Join(e.Settings, "convox", "racks", "dev1")
|
||||
|
||||
_, err = os.Stat(dir)
|
||||
require.True(t, os.IsNotExist(err))
|
||||
|
||||
me.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackUninstallUnknown(t *testing.T) {
|
||||
testClientWait(t, 50*time.Millisecond, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
res, err := testExecute(e, "rack uninstall dev2", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, res.Code)
|
||||
res.RequireStderr(t, []string{"ERROR: could not find rack: dev2"})
|
||||
res.RequireStdout(t, []string{""})
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackUpdate(t *testing.T) {
|
||||
testClientWait(t, 50*time.Millisecond, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
i.On("SystemUpdate", structs.SystemUpdateOptions{Version: options.String("version1")}).Return(nil)
|
||||
i.On("SystemGet").Return(fxSystemUpdating(), nil).Twice()
|
||||
i.On("SystemGet").Return(fxSystem(), nil)
|
||||
i.On("SystemLogs", mock.Anything).Return(testLogs(fxLogsSystem()), nil)
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
res, err := testExecute(e, "rack update version1", nil)
|
||||
me := e.Executor.(*mockstdcli.Executor)
|
||||
me.On("Terminal", "terraform", "init", "-upgrade").Return(nil)
|
||||
me.On("Terminal", "terraform", "apply", "-auto-approve").Return(nil)
|
||||
|
||||
res, err := testExecute(e, "rack update dev1", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{
|
||||
"Updating to version1... ",
|
||||
"TIME system/aws/component log1",
|
||||
"TIME system/aws/component log2",
|
||||
"OK",
|
||||
})
|
||||
|
||||
me.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackUpdateError(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
i.On("SystemUpdate", structs.SystemUpdateOptions{Version: options.String("version1")}).Return(fmt.Errorf("err1"))
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
res, err := testExecute(e, "rack update version1", nil)
|
||||
me := e.Executor.(*mockstdcli.Executor)
|
||||
me.On("Terminal", "terraform", "init", "-upgrade").Return(nil)
|
||||
me.On("Terminal", "terraform", "apply", "-auto-approve").Return(fmt.Errorf("err1"))
|
||||
|
||||
res, err := testExecute(e, "rack update dev1", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, res.Code)
|
||||
res.RequireStderr(t, []string{"ERROR: err1"})
|
||||
res.RequireStdout(t, []string{"Updating to version1... "})
|
||||
res.RequireStdout(t, []string{""})
|
||||
|
||||
me.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRackUpdateUnknown(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
res, err := testExecute(e, "rack update dev2", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, res.Code)
|
||||
res.RequireStderr(t, []string{"ERROR: could not find rack: dev2"})
|
||||
res.RequireStdout(t, []string{""})
|
||||
})
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("racks", "list available racks", Racks, stdcli.CommandOptions{
|
||||
registerWithoutProvider("racks", "list available racks", Racks, stdcli.CommandOptions{
|
||||
Validate: stdcli.Args(0),
|
||||
})
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@ -17,50 +16,34 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRacks(t *testing.T) {
|
||||
func TestRacksNone(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
r := mux.NewRouter()
|
||||
|
||||
r.HandleFunc("/racks", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`[
|
||||
{"name":"foo","organization":{"name":"test"},"status":"running"},
|
||||
{"name":"other","organization":{"name":"test"},"status":"updating"}
|
||||
]`))
|
||||
}).Methods("GET")
|
||||
|
||||
ts := httptest.NewTLSServer(r)
|
||||
|
||||
tsu, err := url.Parse(ts.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(e.Settings, "host"), []byte(tsu.Host), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
me := &mockstdcli.Executor{}
|
||||
me.On("Execute", "kubectl", "get", "ns", "--selector=system=convox,type=rack", "--output=name").Return([]byte("namespace/dev\n"), nil)
|
||||
me.On("Execute", "kubectl", "get", "namespace/dev", "-o", "jsonpath={.metadata.labels.rack}").Return([]byte("dev\n"), nil)
|
||||
e.Executor = me
|
||||
|
||||
res, err := testExecute(e, "racks", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{
|
||||
"NAME STATUS ",
|
||||
"local/dev running ",
|
||||
"test/foo running ",
|
||||
"test/other updating",
|
||||
"NAME STATUS",
|
||||
})
|
||||
|
||||
me.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRacksLocalDisable(t *testing.T) {
|
||||
orig := os.Getenv("CONVOX_LOCAL")
|
||||
os.Setenv("CONVOX_LOCAL", "disable")
|
||||
defer os.Setenv("CONVOX_LOCAL", orig)
|
||||
func TestRacksLocal(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
res, err := testExecute(e, "racks", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{
|
||||
"NAME STATUS ",
|
||||
"dev1 running",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestRacksRemote(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
r := mux.NewRouter()
|
||||
|
||||
@ -79,9 +62,6 @@ func TestRacksLocalDisable(t *testing.T) {
|
||||
err = ioutil.WriteFile(filepath.Join(e.Settings, "host"), []byte(tsu.Host), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
me := &mockstdcli.Executor{}
|
||||
e.Executor = me
|
||||
|
||||
res, err := testExecute(e, "racks", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
@ -91,8 +71,40 @@ func TestRacksLocalDisable(t *testing.T) {
|
||||
"test/foo running ",
|
||||
"test/other updating",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
me.AssertExpectations(t)
|
||||
func TestRacksLocalAndRemote(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
r := mux.NewRouter()
|
||||
|
||||
r.HandleFunc("/racks", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`[
|
||||
{"name":"foo","organization":{"name":"test"},"status":"running"},
|
||||
{"name":"other","organization":{"name":"test"},"status":"updating"}
|
||||
]`))
|
||||
}).Methods("GET")
|
||||
|
||||
ts := httptest.NewTLSServer(r)
|
||||
|
||||
tsu, err := url.Parse(ts.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(e.Settings, "host"), []byte(tsu.Host), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := testExecute(e, "racks", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, res.Code)
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{
|
||||
"NAME STATUS ",
|
||||
"dev1 running ",
|
||||
"test/foo running ",
|
||||
"test/other updating",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/convox/convox/sdk"
|
||||
"github.com/convox/stdcli"
|
||||
)
|
||||
@ -19,31 +17,23 @@ func Switch(rack sdk.Interface, c *stdcli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if rack := c.Arg(0); rack != "" {
|
||||
r, err := matchRack(c, rack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rs := hostRacks(c)
|
||||
|
||||
rs[host] = r.Name
|
||||
|
||||
data, err := json.MarshalIndent(rs, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.SettingWrite("racks", string(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Writef("Switched to <rack>%s</rack>\n", r.Name)
|
||||
name := c.Arg(0)
|
||||
|
||||
if name == "" {
|
||||
c.Writef("%s\n", currentRack(c, host))
|
||||
return nil
|
||||
}
|
||||
|
||||
c.Writef("%s\n", currentRack(c, host))
|
||||
r, err := matchRack(c, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := switchRack(c, r.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Writef("Switched to <rack>%s</rack>\n", r.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ func TestSwitch(t *testing.T) {
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{"Switched to test/foo"})
|
||||
|
||||
data, err := ioutil.ReadFile(filepath.Join(e.Settings, "racks"))
|
||||
data, err := ioutil.ReadFile(filepath.Join(e.Settings, "switch"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fmt.Sprintf("{\n \"%s\": \"test/foo\"\n}", tsu.Host), string(data))
|
||||
})
|
||||
|
||||
14
pkg/cli/testdata/terraform.local.tf
vendored
Normal file
14
pkg/cli/testdata/terraform.local.tf
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
module "system" {
|
||||
source = "github.com/convox/convox//terraform/system/local"
|
||||
|
||||
name = "dev1"
|
||||
release = ""
|
||||
}
|
||||
|
||||
output "api" {
|
||||
value = module.system.api
|
||||
}
|
||||
|
||||
output "provider" {
|
||||
value = "local"
|
||||
}
|
||||
@ -17,13 +17,7 @@ func init() {
|
||||
func Version(rack sdk.Interface, c *stdcli.Context) error {
|
||||
c.Writef("client: <info>%s</info>\n", c.Version())
|
||||
|
||||
host, err := currentHost(c)
|
||||
if err != nil {
|
||||
c.Writef("server: <info>none</info>\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
ep, err := currentEndpoint(c, currentRack(c, host))
|
||||
ep, err := currentEndpoint(c)
|
||||
if err != nil {
|
||||
c.Writef("server: <info>none</info>\n")
|
||||
return nil
|
||||
|
||||
@ -14,9 +14,7 @@ import (
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
me := &mockstdcli.Executor{}
|
||||
me.On("Execute", "kubectl", "get", "ns", "--selector=system=convox,type=rack", "--output=name").Return([]byte("namespace/dev\n"), nil)
|
||||
e.Executor = me
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
err := ioutil.WriteFile(filepath.Join(e.Settings, "host"), []byte("host1"), 0644)
|
||||
require.NoError(t, err)
|
||||
@ -36,9 +34,7 @@ func TestVersion(t *testing.T) {
|
||||
|
||||
func TestVersionError(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
me := &mockstdcli.Executor{}
|
||||
me.On("Execute", "kubectl", "get", "ns", "--selector=system=convox,type=rack", "--output=name").Return([]byte("namespace/dev\n"), nil)
|
||||
e.Executor = me
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://host1"))
|
||||
|
||||
err := ioutil.WriteFile(filepath.Join(e.Settings, "host"), []byte("host1"), 0644)
|
||||
require.NoError(t, err)
|
||||
@ -93,10 +89,7 @@ func TestVersionNoSystemMultipleLocal(t *testing.T) {
|
||||
|
||||
func TestVersionNoSystemSingleLocal(t *testing.T) {
|
||||
testClient(t, func(e *cli.Engine, i *mocksdk.Interface) {
|
||||
me := &mockstdcli.Executor{}
|
||||
me.On("Execute", "kubectl", "get", "ns", "--selector=system=convox,type=rack", "--output=name").Return([]byte("namespace/dev\n"), nil)
|
||||
me.On("Execute", "kubectl", "get", "namespace/dev", "-o", "jsonpath={.metadata.labels.rack}").Return([]byte("dev\n"), nil)
|
||||
e.Executor = me
|
||||
require.NoError(t, testLocalRack(e, "dev1", "local", "https://api.dev.convox"))
|
||||
|
||||
i.On("SystemGet").Return(fxSystemLocal(), nil)
|
||||
|
||||
@ -106,7 +99,7 @@ func TestVersionNoSystemSingleLocal(t *testing.T) {
|
||||
res.RequireStderr(t, []string{""})
|
||||
res.RequireStdout(t, []string{
|
||||
"client: test",
|
||||
"server: dev (rack.dev)",
|
||||
"server: dev1 (api.dev.convox)",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -2,11 +2,8 @@
|
||||
|
||||
package stdcli
|
||||
|
||||
import (
|
||||
io "io"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
import io "io"
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// Executor is an autogenerated mock type for the Executor type
|
||||
type Executor struct {
|
||||
|
||||
19
vendor/github.com/adrg/xdg/.travis.yml
generated
vendored
Normal file
19
vendor/github.com/adrg/xdg/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
- windows
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
git:
|
||||
autocrlf: false
|
||||
before_install:
|
||||
- go get -t -v ./...
|
||||
- go install github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
script:
|
||||
- golangci-lint run --enable-all -D wsl -D gochecknoinits -D gochecknoglobals -D prealloc
|
||||
- go test -v -race ./...
|
||||
77
vendor/github.com/adrg/xdg/CODE_OF_CONDUCT.md
generated
vendored
Normal file
77
vendor/github.com/adrg/xdg/CODE_OF_CONDUCT.md
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age,
|
||||
body size, disability, ethnicity, sex characteristics, gender identity and
|
||||
expression, level of experience, education, socio-economic status, nationality,
|
||||
personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behaviour that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behaviour by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behaviour and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behaviour.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviour that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behaviour may be
|
||||
reported by contacting the project team at adrg@epistack.com. All complaints
|
||||
will be reviewed and investigated and will result in a response that is deemed
|
||||
necessary and appropriate to the circumstances. The project team is obligated to
|
||||
maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 1.4, available at
|
||||
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
135
vendor/github.com/adrg/xdg/CONTRIBUTING.md
generated
vendored
Normal file
135
vendor/github.com/adrg/xdg/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
# Contributing to this project
|
||||
|
||||
Contributions in the form of pull requests, issues or just general feedback,
|
||||
are always welcome. Please take a moment to review this document in order to
|
||||
make the contribution process easy and effective for everyone involved.
|
||||
|
||||
Following these guidelines helps to communicate that you respect the time of
|
||||
the developers managing and developing this open source project. In return,
|
||||
they should reciprocate that respect in addressing your issue or assessing
|
||||
patches and features.
|
||||
|
||||
## Using the issue tracker
|
||||
|
||||
The issue tracker is the preferred channel for [bug reports](#bugs),
|
||||
[features requests](#features) and [submitting pull
|
||||
requests](#pull-requests), but please respect the following restrictions:
|
||||
|
||||
* Please **do not** use the issue tracker for personal support requests (use
|
||||
[Stack Overflow](http://stackoverflow.com) or IRC).
|
||||
* Please **do not** derail or troll issues. Keep the discussion on topic and
|
||||
respect the opinions of others.
|
||||
|
||||
<a name="bugs"></a>
|
||||
## Bug reports
|
||||
|
||||
A bug is a _demonstrable problem_ that is caused by the code in the repository.
|
||||
Good bug reports are extremely helpful - thank you!
|
||||
|
||||
Guidelines for bug reports:
|
||||
|
||||
1. **Use the GitHub issue search** — check if the issue has already been
|
||||
reported.
|
||||
2. **Check if the issue has been fixed** — try to reproduce it using the
|
||||
latest `master` or development branch in the repository.
|
||||
3. **Isolate the problem** — create a reduced test case.
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more
|
||||
information. Please try to be as detailed as possible in your report. What is
|
||||
your environment? What steps will reproduce the issue? What browser(s) and OS
|
||||
experience the problem? What would you expect to be the outcome? All these
|
||||
details will help people to fix any potential bugs.
|
||||
|
||||
Example:
|
||||
|
||||
> Short and descriptive example bug report title
|
||||
>
|
||||
> A summary of the issue and the browser/OS environment in which it occurs. If
|
||||
> suitable, include the steps required to reproduce the bug.
|
||||
>
|
||||
> 1. This is the first step
|
||||
> 2. This is the second step
|
||||
> 3. Further steps, etc.
|
||||
>
|
||||
> `<url>` - a link to the reduced test case
|
||||
>
|
||||
> Any other information you want to share that is relevant to the issue being
|
||||
> reported. This might include the lines of code that you have identified as
|
||||
> causing the bug, and potential solutions (and your opinions on their
|
||||
> merits).
|
||||
|
||||
|
||||
<a name="features"></a>
|
||||
## Feature requests
|
||||
|
||||
Feature requests are welcome. But take a moment to find out whether your idea
|
||||
fits with the scope and aims of the project. It's up to *you* to make a strong
|
||||
case to convince the project's developers of the merits of this feature. Please
|
||||
provide as much detail and context as possible.
|
||||
|
||||
|
||||
<a name="pull-requests"></a>
|
||||
## Pull requests
|
||||
|
||||
Good pull requests - patches, improvements, new features - are a fantastic
|
||||
help. They should remain focused in scope and avoid containing unrelated
|
||||
commits.
|
||||
|
||||
**Please ask first** before embarking on any significant pull request (e.g.
|
||||
implementing features, refactoring code, porting to a different language),
|
||||
otherwise you risk spending a lot of time working on something that the
|
||||
project's developers might not want to merge into the project.
|
||||
|
||||
Please adhere to the coding conventions used throughout a project (indentation,
|
||||
accurate comments, etc.) and any other requirements (such as test coverage).
|
||||
|
||||
Follow this process if you'd like your work considered for inclusion in the
|
||||
project:
|
||||
|
||||
1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork,
|
||||
and configure the remotes:
|
||||
|
||||
```bash
|
||||
# Clone your fork of the repo into the current directory
|
||||
git clone https://github.com/<your-username>/<repo-name>
|
||||
# Navigate to the newly cloned directory
|
||||
cd <repo-name>
|
||||
# Assign the original repo to a remote called "upstream"
|
||||
git remote add upstream https://github.com/<upstream-owner>/<repo-name>
|
||||
```
|
||||
|
||||
2. If you cloned a while ago, get the latest changes from upstream:
|
||||
|
||||
```bash
|
||||
git checkout <dev-branch>
|
||||
git pull upstream <dev-branch>
|
||||
```
|
||||
|
||||
3. Create a new topic branch (off the main project development branch) to
|
||||
contain your feature, change, or fix:
|
||||
|
||||
```bash
|
||||
git checkout -b <topic-branch-name>
|
||||
```
|
||||
|
||||
4. Commit your changes in logical chunks and use descriptive commit messages.
|
||||
Use [interactive rebase](https://help.github.com/articles/interactive-rebase)
|
||||
to tidy up your commits before making them public.
|
||||
|
||||
5. Locally merge (or rebase) the upstream development branch into your topic branch:
|
||||
|
||||
```bash
|
||||
git pull [--rebase] upstream <dev-branch>
|
||||
```
|
||||
|
||||
6. Push your topic branch up to your fork:
|
||||
|
||||
```bash
|
||||
git push origin <topic-branch-name>
|
||||
```
|
||||
|
||||
7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
|
||||
with a clear title and description.
|
||||
|
||||
**IMPORTANT**: By submitting a patch, you agree to allow the project owner to
|
||||
license your work under the same license as that used by the project.
|
||||
21
vendor/github.com/adrg/xdg/LICENSE
generated
vendored
Normal file
21
vendor/github.com/adrg/xdg/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Adrian-George Bostan <adrg@epistack.com>
|
||||
|
||||
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.
|
||||
187
vendor/github.com/adrg/xdg/README.md
generated
vendored
Normal file
187
vendor/github.com/adrg/xdg/README.md
generated
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
xdg
|
||||
===
|
||||
[](https://travis-ci.org/adrg/xdg)
|
||||
[](https://godoc.org/github.com/adrg/xdg)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://goreportcard.com/report/github.com/adrg/xdg)
|
||||
|
||||
Provides an implementation of the [XDG Base Directory Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html).
|
||||
The specification defines a set of standard paths for storing application files,
|
||||
including data and configuration files. For portability and flexibility reasons,
|
||||
applications should use the XDG defined locations instead of hardcoding paths.
|
||||
The package also includes the locations of well known user directories.
|
||||
The current implementation supports Windows, Mac OS and most flavors of Unix.
|
||||
|
||||
Full documentation can be found at: https://godoc.org/github.com/adrg/xdg
|
||||
|
||||
## Installation
|
||||
go get github.com/adrg/xdg
|
||||
|
||||
## Default locations
|
||||
|
||||
The package defines sensible defaults for XDG variables which are empty or not
|
||||
present in the environment.
|
||||
|
||||
#### XDG Base Directory
|
||||
|
||||
| | Unix | Mac OS | Windows |
|
||||
| :--- | :--- | :----- | :--- |
|
||||
| XDG_DATA_HOME | `~/.local/share` | `~/Library/Application Support` | `%LOCALAPPDATA%` |
|
||||
| XDG_DATA_DIRS | `/usr/local/share`<br/>`/usr/share` | `/Library/Application Support` | `%APPDATA%\Roaming`<br/>`%PROGRAMDATA%` |
|
||||
| XDG_CONFIG_HOME | `~/.config` | `~/Library/Preferences` | `%LOCALAPPDATA%` |
|
||||
| XDG_CONFIG_DIRS | `/etc/xdg` | `/Library/Preferences` | `%PROGRAMDATA%` |
|
||||
| XDG_CACHE_HOME | `~/.cache` | `~/Library/Caches` | `%LOCALAPPDATA%\cache` |
|
||||
| XDG_RUNTIME_DIR | `/run/user/UID` | `~/Library/Application Support` | `%LOCALAPPDATA%` |
|
||||
|
||||
#### XDG user directories
|
||||
|
||||
| | Unix | Mac OS | Windows |
|
||||
| :--- | :--- | :----- | :--- |
|
||||
| XDG_DESKTOP_DIR | `~/Desktop` | `~/Desktop` | `%USERPROFILE%/Desktop` |
|
||||
| XDG_DOWNLOAD_DIR | `~/Downloads` | `~/Downloads` | `%USERPROFILE%/Downloads` |
|
||||
| XDG_DOCUMENTS_DIR | `~/Documents` | `~/Documents` | `%USERPROFILE%/Documents` |
|
||||
| XDG_MUSIC_DIR | `~/Music` | `~/Music` | `%USERPROFILE%/Music` |
|
||||
| XDG_PICTURES_DIR | `~/Pictures` | `~/Pictures` | `%USERPROFILE%/Pictures` |
|
||||
| XDG_VIDEOS_DIR | `~/Videos` | `~/Movies` | `%USERPROFILE%/Videos` |
|
||||
| XDG_TEMPLATES_DIR | `~/Templates` | `~/Templates` | `%USERPROFILE%/Templates` |
|
||||
| XDG_PUBLICSHARE_DIR | `~/Public` | `~/Public` | `%PUBLIC%` |
|
||||
|
||||
#### Non-standard directories
|
||||
|
||||
Application directories
|
||||
|
||||
```
|
||||
Unix:
|
||||
- $XDG_DATA_HOME/applications
|
||||
- ~/.local/share/applications
|
||||
- /usr/local/share/applications
|
||||
- /usr/share/applications
|
||||
- $XDG_DATA_DIRS/applications
|
||||
|
||||
Mac OS:
|
||||
- /Applications
|
||||
|
||||
Windows:
|
||||
- %APPDATA%\Roaming\Microsoft\Windows\Start Menu\Programs
|
||||
```
|
||||
|
||||
Font Directories
|
||||
|
||||
```
|
||||
Unix:
|
||||
- $XDG_DATA_HOME/fonts
|
||||
- ~/.fonts
|
||||
- ~/.local/share/fonts
|
||||
- /usr/local/share/fonts
|
||||
- /usr/share/fonts
|
||||
- $XDG_DATA_DIRS/fonts
|
||||
|
||||
Mac OS:
|
||||
- ~/Library/Fonts
|
||||
- /Library/Fonts
|
||||
- /System/Library/Fonts
|
||||
- /Network/Library/Fonts
|
||||
|
||||
Windows:
|
||||
- %windir%\Fonts
|
||||
- %LOCALAPPDATA%\Microsoft\Windows\Fonts
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
#### XDG Base Directory
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/adrg/xdg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// XDG Base Directory paths.
|
||||
log.Println("Home config directory:", xdg.DataHome)
|
||||
log.Println("Data directories:", xdg.DataDirs)
|
||||
log.Println("Home config directory:", xdg.ConfigHome)
|
||||
log.Println("Config directories:", xdg.ConfigDirs)
|
||||
log.Println("Cache directory:", xdg.CacheHome)
|
||||
log.Println("Runtime directory:", xdg.RuntimeDir)
|
||||
|
||||
// Non-standard directories.
|
||||
log.Println("Application directories:", xdg.ApplicationDirs)
|
||||
log.Println("Font directories:", xdg.FontDirs)
|
||||
|
||||
// Obtain a suitable location for application config files.
|
||||
// ConfigFile takes one parameter which must contain the name of the file,
|
||||
// but it can also contain a set of parent directories. If the directories
|
||||
// don't exists, they will be created relative to the base config directory.
|
||||
configFilePath, err := xdg.ConfigFile("appname/config.yaml")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println("Save the config file at:", configFilePath)
|
||||
|
||||
// For other types of application files use:
|
||||
// xdg.DataFile()
|
||||
// xdg.CacheFile()
|
||||
// xdg.RuntimeFile()
|
||||
|
||||
// Finding application config files.
|
||||
// SearchConfigFile takes one parameter which must contain the name of
|
||||
// the file, but it can also contain a set of parent directories relative
|
||||
// to the config search paths (xdg.ConfigHome and xdg.ConfigDirs).
|
||||
configFilePath, err = xdg.SearchConfigFile("appname/config.yaml")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println("Config file was found at:", configFilePath)
|
||||
|
||||
// For other types of application files use:
|
||||
// xdg.SearchDataFile()
|
||||
// xdg.SearchCacheFile()
|
||||
// xdg.SearchRuntimeFile()
|
||||
}
|
||||
```
|
||||
|
||||
#### XDG user directories
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/adrg/xdg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// XDG user directories.
|
||||
log.Println("Desktop directory:", xdg.UserDirs.Desktop)
|
||||
log.Println("Download directory:", xdg.UserDirs.Download)
|
||||
log.Println("Documents directory:", xdg.UserDirs.Documents)
|
||||
log.Println("Music directory:", xdg.UserDirs.Music)
|
||||
log.Println("Pictures directory:", xdg.UserDirs.Pictures)
|
||||
log.Println("Videos directory:", xdg.UserDirs.Videos)
|
||||
log.Println("Templates directory:", xdg.UserDirs.Templates)
|
||||
log.Println("Public directory:", xdg.UserDirs.PublicShare)
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
For more information see the
|
||||
[XDG Base Directory Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) and
|
||||
[XDG user directories](https://wiki.archlinux.org/index.php/XDG_user_directories).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions in the form of pull requests, issues or just general feedback,
|
||||
are always welcome.
|
||||
See [CONTRIBUTING.MD](https://github.com/adrg/xdg/blob/master/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
Copyright (c) 2014 Adrian-George Bostan.
|
||||
|
||||
This project is licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
See [LICENSE](https://github.com/adrg/xdg/blob/master/LICENSE) for more details.
|
||||
78
vendor/github.com/adrg/xdg/base_dirs.go
generated
vendored
Normal file
78
vendor/github.com/adrg/xdg/base_dirs.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
package xdg
|
||||
|
||||
import "os"
|
||||
|
||||
// XDG Base Directory environment variables.
|
||||
var (
|
||||
envDataHome = "XDG_DATA_HOME"
|
||||
envDataDirs = "XDG_DATA_DIRS"
|
||||
envConfigHome = "XDG_CONFIG_HOME"
|
||||
envConfigDirs = "XDG_CONFIG_DIRS"
|
||||
envCacheHome = "XDG_CACHE_HOME"
|
||||
envRuntimeDir = "XDG_RUNTIME_DIR"
|
||||
)
|
||||
|
||||
type baseDirectories struct {
|
||||
dataHome string
|
||||
data []string
|
||||
configHome string
|
||||
config []string
|
||||
cacheHome string
|
||||
runtime string
|
||||
|
||||
// Non-standard directories.
|
||||
fonts []string
|
||||
applications []string
|
||||
}
|
||||
|
||||
func (bd baseDirectories) dataFile(relPath string) (string, error) {
|
||||
return createPath(relPath, append([]string{bd.dataHome}, bd.data...))
|
||||
}
|
||||
|
||||
func (bd baseDirectories) configFile(relPath string) (string, error) {
|
||||
return createPath(relPath, append([]string{bd.configHome}, bd.config...))
|
||||
}
|
||||
|
||||
func (bd baseDirectories) cacheFile(relPath string) (string, error) {
|
||||
return createPath(relPath, []string{bd.cacheHome})
|
||||
}
|
||||
|
||||
func (bd baseDirectories) runtimeFile(relPath string) (string, error) {
|
||||
fi, err := os.Lstat(bd.runtime)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return createPath(relPath, []string{bd.runtime})
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
// The runtime directory must be owned by the user.
|
||||
if err = os.Chown(bd.runtime, os.Getuid(), os.Getgid()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
// For security reasons, the runtime directory cannot be a symlink.
|
||||
if err = os.Remove(bd.runtime); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return createPath(relPath, []string{bd.runtime})
|
||||
}
|
||||
|
||||
func (bd baseDirectories) searchDataFile(relPath string) (string, error) {
|
||||
return searchFile(relPath, append([]string{bd.dataHome}, bd.data...))
|
||||
}
|
||||
|
||||
func (bd baseDirectories) searchConfigFile(relPath string) (string, error) {
|
||||
return searchFile(relPath, append([]string{bd.configHome}, bd.config...))
|
||||
}
|
||||
|
||||
func (bd baseDirectories) searchCacheFile(relPath string) (string, error) {
|
||||
return searchFile(relPath, []string{bd.cacheHome})
|
||||
}
|
||||
|
||||
func (bd baseDirectories) searchRuntimeFile(relPath string) (string, error) {
|
||||
return searchFile(relPath, []string{bd.runtime})
|
||||
}
|
||||
1
vendor/github.com/adrg/xdg/go.mod
generated
vendored
Normal file
1
vendor/github.com/adrg/xdg/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module github.com/adrg/xdg
|
||||
37
vendor/github.com/adrg/xdg/paths_darwin.go
generated
vendored
Normal file
37
vendor/github.com/adrg/xdg/paths_darwin.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package xdg
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func initBaseDirs(home string) {
|
||||
// Initialize base directories.
|
||||
baseDirs.dataHome = xdgPath(envDataHome, filepath.Join(home, "Library", "Application Support"))
|
||||
baseDirs.data = xdgPaths(envDataDirs, "/Library/Application Support")
|
||||
baseDirs.configHome = xdgPath(envConfigHome, filepath.Join(home, "Library", "Preferences"))
|
||||
baseDirs.config = xdgPaths(envConfigDirs, "/Library/Preferences")
|
||||
baseDirs.cacheHome = xdgPath(envCacheHome, filepath.Join(home, "Library", "Caches"))
|
||||
baseDirs.runtime = xdgPath(envRuntimeDir, filepath.Join(home, "Library", "Application Support"))
|
||||
|
||||
// Initialize non-standard directories.
|
||||
baseDirs.applications = []string{
|
||||
"/Applications",
|
||||
}
|
||||
baseDirs.fonts = []string{
|
||||
filepath.Join(home, "Library/Fonts"),
|
||||
"/Library/Fonts",
|
||||
"/System/Library/Fonts",
|
||||
"/Network/Library/Fonts",
|
||||
}
|
||||
}
|
||||
|
||||
func initUserDirs(home string) {
|
||||
UserDirs.Desktop = xdgPath(envDesktopDir, filepath.Join(home, "Desktop"))
|
||||
UserDirs.Download = xdgPath(envDownloadDir, filepath.Join(home, "Downloads"))
|
||||
UserDirs.Documents = xdgPath(envDocumentsDir, filepath.Join(home, "Documents"))
|
||||
UserDirs.Music = xdgPath(envMusicDir, filepath.Join(home, "Music"))
|
||||
UserDirs.Pictures = xdgPath(envPicturesDir, filepath.Join(home, "Pictures"))
|
||||
UserDirs.Videos = xdgPath(envVideosDir, filepath.Join(home, "Movies"))
|
||||
UserDirs.Templates = xdgPath(envTemplatesDir, filepath.Join(home, "Templates"))
|
||||
UserDirs.PublicShare = xdgPath(envPublicShareDir, filepath.Join(home, "Public"))
|
||||
}
|
||||
54
vendor/github.com/adrg/xdg/paths_unix.go
generated
vendored
Normal file
54
vendor/github.com/adrg/xdg/paths_unix.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// +build aix dragonfly freebsd linux nacl netbsd openbsd solaris
|
||||
|
||||
package xdg
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func initBaseDirs(home string) {
|
||||
// Initialize base directories.
|
||||
baseDirs.dataHome = xdgPath(envDataHome, filepath.Join(home, ".local", "share"))
|
||||
baseDirs.data = xdgPaths(envDataDirs, "/usr/local/share", "/usr/share")
|
||||
baseDirs.configHome = xdgPath(envConfigHome, filepath.Join(home, ".config"))
|
||||
baseDirs.config = xdgPaths(envConfigDirs, "/etc/xdg")
|
||||
baseDirs.cacheHome = xdgPath(envCacheHome, filepath.Join(home, ".cache"))
|
||||
baseDirs.runtime = xdgPath(envRuntimeDir, filepath.Join("/run/user", strconv.Itoa(os.Getuid())))
|
||||
|
||||
// Initialize non-standard directories.
|
||||
appDirs := []string{
|
||||
filepath.Join(baseDirs.dataHome, "applications"),
|
||||
filepath.Join(home, ".local/share/applications"),
|
||||
"/usr/local/share/applications",
|
||||
"/usr/share/applications",
|
||||
}
|
||||
|
||||
fontDirs := []string{
|
||||
filepath.Join(baseDirs.dataHome, "fonts"),
|
||||
filepath.Join(home, ".fonts"),
|
||||
filepath.Join(home, ".local/share/fonts"),
|
||||
"/usr/local/share/fonts",
|
||||
"/usr/share/fonts",
|
||||
}
|
||||
|
||||
for _, dir := range baseDirs.data {
|
||||
appDirs = append(appDirs, filepath.Join(dir, "applications"))
|
||||
fontDirs = append(fontDirs, filepath.Join(dir, "fonts"))
|
||||
}
|
||||
|
||||
baseDirs.applications = uniquePaths(appDirs)
|
||||
baseDirs.fonts = uniquePaths(fontDirs)
|
||||
}
|
||||
|
||||
func initUserDirs(home string) {
|
||||
UserDirs.Desktop = xdgPath(envDesktopDir, filepath.Join(home, "Desktop"))
|
||||
UserDirs.Download = xdgPath(envDownloadDir, filepath.Join(home, "Downloads"))
|
||||
UserDirs.Documents = xdgPath(envDocumentsDir, filepath.Join(home, "Documents"))
|
||||
UserDirs.Music = xdgPath(envMusicDir, filepath.Join(home, "Music"))
|
||||
UserDirs.Pictures = xdgPath(envPicturesDir, filepath.Join(home, "Pictures"))
|
||||
UserDirs.Videos = xdgPath(envVideosDir, filepath.Join(home, "Videos"))
|
||||
UserDirs.Templates = xdgPath(envTemplatesDir, filepath.Join(home, "Templates"))
|
||||
UserDirs.PublicShare = xdgPath(envPublicShareDir, filepath.Join(home, "Public"))
|
||||
}
|
||||
69
vendor/github.com/adrg/xdg/paths_windows.go
generated
vendored
Normal file
69
vendor/github.com/adrg/xdg/paths_windows.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
package xdg
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func initBaseDirs(home string) {
|
||||
appDataDir := os.Getenv("APPDATA")
|
||||
if appDataDir == "" {
|
||||
appDataDir = filepath.Join(home, "AppData")
|
||||
}
|
||||
roamingAppDataDir := filepath.Join(appDataDir, "Roaming")
|
||||
|
||||
localAppDataDir := os.Getenv("LOCALAPPDATA")
|
||||
if localAppDataDir == "" {
|
||||
localAppDataDir = filepath.Join(appDataDir, "Local")
|
||||
}
|
||||
|
||||
programDataDir := os.Getenv("PROGRAMDATA")
|
||||
if programDataDir == "" {
|
||||
if systemDrive := os.Getenv("SystemDrive"); systemDrive != "" {
|
||||
programDataDir = filepath.Join(systemDrive, "ProgramData")
|
||||
} else {
|
||||
programDataDir = home
|
||||
}
|
||||
}
|
||||
|
||||
winDir := os.Getenv("windir")
|
||||
if winDir == "" {
|
||||
winDir = os.Getenv("SystemRoot")
|
||||
if winDir == "" {
|
||||
winDir = home
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize base directories.
|
||||
baseDirs.dataHome = xdgPath(envDataHome, localAppDataDir)
|
||||
baseDirs.data = xdgPaths(envDataDirs, roamingAppDataDir, programDataDir)
|
||||
baseDirs.configHome = xdgPath(envConfigHome, localAppDataDir)
|
||||
baseDirs.config = xdgPaths(envConfigDirs, programDataDir)
|
||||
baseDirs.cacheHome = xdgPath(envCacheHome, filepath.Join(localAppDataDir, "cache"))
|
||||
baseDirs.runtime = xdgPath(envRuntimeDir, localAppDataDir)
|
||||
|
||||
// Initialize non-standard directories.
|
||||
baseDirs.applications = []string{
|
||||
filepath.Join(roamingAppDataDir, "Microsoft", "Windows", "Start Menu", "Programs"),
|
||||
}
|
||||
baseDirs.fonts = []string{
|
||||
filepath.Join(winDir, "Fonts"),
|
||||
filepath.Join(localAppDataDir, "Microsoft", "Windows", "Fonts"),
|
||||
}
|
||||
}
|
||||
|
||||
func initUserDirs(home string) {
|
||||
publicDir := os.Getenv("PUBLIC")
|
||||
if publicDir == "" {
|
||||
publicDir = filepath.Join(home, "Public")
|
||||
}
|
||||
|
||||
UserDirs.Desktop = xdgPath(envDesktopDir, filepath.Join(home, "Desktop"))
|
||||
UserDirs.Download = xdgPath(envDownloadDir, filepath.Join(home, "Downloads"))
|
||||
UserDirs.Documents = xdgPath(envDocumentsDir, filepath.Join(home, "Documents"))
|
||||
UserDirs.Music = xdgPath(envMusicDir, filepath.Join(home, "Music"))
|
||||
UserDirs.Pictures = xdgPath(envPicturesDir, filepath.Join(home, "Pictures"))
|
||||
UserDirs.Videos = xdgPath(envVideosDir, filepath.Join(home, "Videos"))
|
||||
UserDirs.Templates = xdgPath(envTemplatesDir, filepath.Join(home, "Templates"))
|
||||
UserDirs.PublicShare = xdgPath(envPublicShareDir, publicDir)
|
||||
}
|
||||
40
vendor/github.com/adrg/xdg/user_dirs.go
generated
vendored
Normal file
40
vendor/github.com/adrg/xdg/user_dirs.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package xdg
|
||||
|
||||
// XDG user directories environment variables.
|
||||
var (
|
||||
envDesktopDir = "XDG_DESKTOP_DIR"
|
||||
envDownloadDir = "XDG_DOWNLOAD_DIR"
|
||||
envDocumentsDir = "XDG_DOCUMENTS_DIR"
|
||||
envMusicDir = "XDG_MUSIC_DIR"
|
||||
envPicturesDir = "XDG_PICTURES_DIR"
|
||||
envVideosDir = "XDG_VIDEOS_DIR"
|
||||
envTemplatesDir = "XDG_TEMPLATES_DIR"
|
||||
envPublicShareDir = "XDG_PUBLICSHARE_DIR"
|
||||
)
|
||||
|
||||
// UserDirectories defines the locations of well known user directories.
|
||||
type UserDirectories struct {
|
||||
// Desktop defines the location of the user's desktop directory.
|
||||
Desktop string
|
||||
|
||||
// Download defines a suitable location for user downloaded files.
|
||||
Download string
|
||||
|
||||
// Documents defines a suitable location for user document files.
|
||||
Documents string
|
||||
|
||||
// Music defines a suitable location for user audio files.
|
||||
Music string
|
||||
|
||||
// Pictures defines a suitable location for user image files.
|
||||
Pictures string
|
||||
|
||||
// VideosDir defines a suitable location for user video files.
|
||||
Videos string
|
||||
|
||||
// Templates defines a suitable location for user template files.
|
||||
Templates string
|
||||
|
||||
// PublicShare defines a suitable location for user shared files.
|
||||
PublicShare string
|
||||
}
|
||||
126
vendor/github.com/adrg/xdg/utils.go
generated
vendored
Normal file
126
vendor/github.com/adrg/xdg/utils.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
package xdg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func homeDir() string {
|
||||
homeEnv := "HOME"
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
homeEnv = "USERPROFILE"
|
||||
case "plan9":
|
||||
homeEnv = "home"
|
||||
}
|
||||
|
||||
if home := os.Getenv(homeEnv); home != "" {
|
||||
return home
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "nacl":
|
||||
return "/"
|
||||
case "darwin":
|
||||
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
|
||||
return "/"
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func exists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
return err == nil || os.IsExist(err)
|
||||
}
|
||||
|
||||
func expandPath(path, homeDir string) string {
|
||||
if path == "" || homeDir == "" {
|
||||
return path
|
||||
}
|
||||
if path[0] == '~' {
|
||||
return filepath.Join(homeDir, path[1:])
|
||||
}
|
||||
if strings.HasPrefix(path, "$HOME") {
|
||||
return filepath.Join(homeDir, path[5:])
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
func createPath(name string, paths []string) (string, error) {
|
||||
var searchedPaths []string
|
||||
for _, p := range paths {
|
||||
path := filepath.Join(p, name)
|
||||
dir := filepath.Dir(path)
|
||||
|
||||
if exists(dir) {
|
||||
return path, nil
|
||||
}
|
||||
if err := os.MkdirAll(dir, os.ModeDir|0700); err == nil {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
searchedPaths = append(searchedPaths, dir)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not create any of the following paths: %s",
|
||||
strings.Join(searchedPaths, ", "))
|
||||
}
|
||||
|
||||
func searchFile(name string, paths []string) (string, error) {
|
||||
var searchedPaths []string
|
||||
for _, p := range paths {
|
||||
path := filepath.Join(p, name)
|
||||
if exists(path) {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
searchedPaths = append(searchedPaths, filepath.Dir(path))
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not locate `%s` in any of the following paths: %s",
|
||||
filepath.Base(name), strings.Join(searchedPaths, ", "))
|
||||
}
|
||||
|
||||
func xdgPath(name, defaultPath string) string {
|
||||
dir := expandPath(os.Getenv(name), Home)
|
||||
if dir != "" && filepath.IsAbs(dir) {
|
||||
return dir
|
||||
}
|
||||
|
||||
return defaultPath
|
||||
}
|
||||
|
||||
func xdgPaths(name string, defaultPaths ...string) []string {
|
||||
dirs := uniquePaths(filepath.SplitList(os.Getenv(name)))
|
||||
if len(dirs) != 0 {
|
||||
return dirs
|
||||
}
|
||||
|
||||
return uniquePaths(defaultPaths)
|
||||
}
|
||||
|
||||
func uniquePaths(paths []string) []string {
|
||||
var uniq []string
|
||||
registry := map[string]struct{}{}
|
||||
|
||||
for _, p := range paths {
|
||||
dir := expandPath(p, Home)
|
||||
if dir == "" || !filepath.IsAbs(dir) {
|
||||
continue
|
||||
}
|
||||
if _, ok := registry[dir]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
registry[dir] = struct{}{}
|
||||
uniq = append(uniq, dir)
|
||||
}
|
||||
|
||||
return uniq
|
||||
}
|
||||
180
vendor/github.com/adrg/xdg/xdg.go
generated
vendored
Normal file
180
vendor/github.com/adrg/xdg/xdg.go
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
Package xdg provides an implementation of the XDG Base Directory
|
||||
Specification. The specification defines a set of standard paths for storing
|
||||
application files including data and configuration files. For portability and
|
||||
flexibility reasons, applications should use the XDG defined locations instead
|
||||
of hardcoding paths. The package also includes the locations of well known user
|
||||
directories. The current implementation supports Windows, Mac OS and most
|
||||
flavors of Unix.
|
||||
|
||||
For more information regarding the XDG Base Directory Specification see:
|
||||
https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
|
||||
For more information regarding the XDG user directories see:
|
||||
https://wiki.archlinux.org/index.php/XDG_user_directories
|
||||
*/
|
||||
package xdg
|
||||
|
||||
var (
|
||||
// Home contains the path of the user's home directory.
|
||||
Home string
|
||||
|
||||
// DataHome defines the base directory relative to which user-specific
|
||||
// data files should be stored. This directory is defined by the
|
||||
// environment variable $XDG_DATA_HOME. If this variable is not set,
|
||||
// a default equal to $HOME/.local/share should be used.
|
||||
DataHome string
|
||||
|
||||
// DataDirs defines the preference-ordered set of base directories to
|
||||
// search for data files in addition to the DataHome base directory.
|
||||
// This set of directories is defined by the environment variable
|
||||
// $XDG_DATA_DIRS. If this variable is not set, the default directories
|
||||
// to be used are /usr/local/share and /usr/share, in that order. The
|
||||
// DataHome directory is considered more important than any of the
|
||||
// directories defined by DataDirs. Therefore, user data files should be
|
||||
// written relative to the DataHome directory, if possible.
|
||||
DataDirs []string
|
||||
|
||||
// ConfigHome defines the base directory relative to which user-specific
|
||||
// configuration files should be written. This directory is defined by
|
||||
// the environment variable $XDG_CONFIG_HOME. If this variable is not
|
||||
// not set, a default equal to $HOME/.config should be used.
|
||||
ConfigHome string
|
||||
|
||||
// ConfigDirs defines the preference-ordered set of base directories to
|
||||
// search for configuration files in addition to the ConfigHome base
|
||||
// directory. This set of directories is defined by the environment
|
||||
// variable $XDG_CONFIG_DIRS. If this variable is not set, a default
|
||||
// equal to /etc/xdg should be used. The ConfigHome directory is
|
||||
// considered more important than any of the directories defined by
|
||||
// ConfigDirs. Therefore, user config files should be written
|
||||
// relative to the ConfigHome directory, if possible.
|
||||
ConfigDirs []string
|
||||
|
||||
// CacheHome defines the base directory relative to which user-specific
|
||||
// non-essential (cached) data should be written. This directory is
|
||||
// defined by the environment variable $XDG_CACHE_HOME. If this variable
|
||||
// is not set, a default equal to $HOME/.cache should be used.
|
||||
CacheHome string
|
||||
|
||||
// RuntimeDir defines the base directory relative to which user-specific
|
||||
// non-essential runtime files and other file objects (such as sockets,
|
||||
// named pipes, etc.) should be stored. This directory is defined by the
|
||||
// environment variable $XDG_RUNTIME_DIR. If this variable is not set,
|
||||
// applications should fall back to a replacement directory with similar
|
||||
// capabilities. Applications should use this directory for communication
|
||||
// and synchronization purposes and should not place larger files in it,
|
||||
// since it might reside in runtime memory and cannot necessarily be
|
||||
// swapped out to disk.
|
||||
RuntimeDir string
|
||||
|
||||
// UserDirs defines the locations of well known user directories.
|
||||
UserDirs UserDirectories
|
||||
|
||||
// FontDirs defines the common locations where font files are stored.
|
||||
FontDirs []string
|
||||
|
||||
// ApplicationDirs defines the common locations of applications.
|
||||
ApplicationDirs []string
|
||||
|
||||
// baseDirs defines the locations of base directories.
|
||||
baseDirs baseDirectories
|
||||
)
|
||||
|
||||
// Reload refreshes base and user directories by reading the environment.
|
||||
// Defaults are applied for XDG variables which are empty or not present
|
||||
// in the environment.
|
||||
func Reload() {
|
||||
// Initialize home directory.
|
||||
Home = homeDir()
|
||||
|
||||
// Initialize base directories.
|
||||
initBaseDirs(Home)
|
||||
DataHome = baseDirs.dataHome
|
||||
DataDirs = baseDirs.data
|
||||
ConfigHome = baseDirs.configHome
|
||||
ConfigDirs = baseDirs.config
|
||||
CacheHome = baseDirs.cacheHome
|
||||
RuntimeDir = baseDirs.runtime
|
||||
FontDirs = baseDirs.fonts
|
||||
ApplicationDirs = baseDirs.applications
|
||||
|
||||
// Initialize user directories.
|
||||
initUserDirs(Home)
|
||||
}
|
||||
|
||||
// DataFile returns a suitable location for the specified data file.
|
||||
// The relPath parameter must contain the name of the data file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.data).
|
||||
// If the specified directories do not exist, they will be created relative
|
||||
// to the base data directory. On failure, an error containing the
|
||||
// attempted paths is returned.
|
||||
func DataFile(relPath string) (string, error) {
|
||||
return baseDirs.dataFile(relPath)
|
||||
}
|
||||
|
||||
// ConfigFile returns a suitable location for the specified config file.
|
||||
// The relPath parameter must contain the name of the config file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.yaml).
|
||||
// If the specified directories do not exist, they will be created relative
|
||||
// to the base config directory. On failure, an error containing the
|
||||
// attempted paths is returned.
|
||||
func ConfigFile(relPath string) (string, error) {
|
||||
return baseDirs.configFile(relPath)
|
||||
}
|
||||
|
||||
// CacheFile returns a suitable location for the specified cache file.
|
||||
// The relPath parameter must contain the name of the cache file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.cache).
|
||||
// If the specified directories do not exist, they will be created relative
|
||||
// to the base cache directory. On failure, an error containing the
|
||||
// attempted paths is returned.
|
||||
func CacheFile(relPath string) (string, error) {
|
||||
return baseDirs.cacheFile(relPath)
|
||||
}
|
||||
|
||||
// RuntimeFile returns a suitable location for the specified runtime file.
|
||||
// The relPath parameter must contain the name of the runtime file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.pid).
|
||||
// If the specified directories do not exist, they will be created relative
|
||||
// to the base runtime directory. On failure, an error containing the
|
||||
// attempted paths is returned.
|
||||
func RuntimeFile(relPath string) (string, error) {
|
||||
return baseDirs.runtimeFile(relPath)
|
||||
}
|
||||
|
||||
// SearchDataFile searches for specified file in the data search paths.
|
||||
// The relPath parameter must contain the name of the data file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.data). If the
|
||||
// file cannot be found, an error specifying the searched paths is returned.
|
||||
func SearchDataFile(relPath string) (string, error) {
|
||||
return baseDirs.searchDataFile(relPath)
|
||||
}
|
||||
|
||||
// SearchConfigFile searches for the specified file in config search paths.
|
||||
// The relPath parameter must contain the name of the config file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.yaml). If the
|
||||
// file cannot be found, an error specifying the searched paths is returned.
|
||||
func SearchConfigFile(relPath string) (string, error) {
|
||||
return baseDirs.searchConfigFile(relPath)
|
||||
}
|
||||
|
||||
// SearchCacheFile searches for the specified file in the cache search path.
|
||||
// The relPath parameter must contain the name of the cache file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.cache). If the
|
||||
// file cannot be found, an error specifying the searched path is returned.
|
||||
func SearchCacheFile(relPath string) (string, error) {
|
||||
return baseDirs.searchCacheFile(relPath)
|
||||
}
|
||||
|
||||
// SearchRuntimeFile searches for the specified file in the runtime search path.
|
||||
// The relPath parameter must contain the name of the runtime file, and
|
||||
// optionally, a set of parent directories (e.g. appname/app.pid). If the
|
||||
// file cannot be found, an error specifying the searched path is returned.
|
||||
func SearchRuntimeFile(relPath string) (string, error) {
|
||||
return baseDirs.searchRuntimeFile(relPath)
|
||||
}
|
||||
|
||||
func init() {
|
||||
Reload()
|
||||
}
|
||||
4
vendor/github.com/convox/stdcli/context.go
generated
vendored
4
vendor/github.com/convox/stdcli/context.go
generated
vendored
@ -160,6 +160,10 @@ func (c *Context) SettingDelete(name string) error {
|
||||
return c.engine.SettingDelete(name)
|
||||
}
|
||||
|
||||
func (c *Context) SettingDirectory(name string) (string, error) {
|
||||
return c.engine.SettingDirectory(name)
|
||||
}
|
||||
|
||||
func (c *Context) SettingRead(name string) (string, error) {
|
||||
return c.engine.SettingRead(name)
|
||||
}
|
||||
|
||||
20
vendor/github.com/convox/stdcli/engine.go
generated
vendored
20
vendor/github.com/convox/stdcli/engine.go
generated
vendored
@ -3,10 +3,7 @@ package stdcli
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
type Engine struct {
|
||||
@ -75,20 +72,3 @@ func (e *Engine) ExecuteContext(ctx context.Context, args []string) int {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Engine) settingFile(name string) (string, error) {
|
||||
if dir := e.Settings; dir != "" {
|
||||
return filepath.Join(dir, name), nil
|
||||
}
|
||||
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filepath.Join(home, fmt.Sprintf(".%s", e.Name), name), nil
|
||||
}
|
||||
|
||||
func (e *Engine) localSettingDir() string {
|
||||
return fmt.Sprintf(".%s", e.Name)
|
||||
}
|
||||
|
||||
9
vendor/github.com/convox/stdcli/go.mod
generated
vendored
Normal file
9
vendor/github.com/convox/stdcli/go.mod
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
module github.com/convox/stdcli
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/adrg/xdg v0.2.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad
|
||||
)
|
||||
12
vendor/github.com/convox/stdcli/go.sum
generated
vendored
Normal file
12
vendor/github.com/convox/stdcli/go.sum
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
github.com/adrg/xdg v0.2.1 h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=
|
||||
github.com/adrg/xdg v0.2.1/go.mod h1:ZuOshBmzV4Ta+s23hdfFZnBsdzmoR3US0d7ErpqSbTQ=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
29
vendor/github.com/convox/stdcli/setting.go
generated
vendored
29
vendor/github.com/convox/stdcli/setting.go
generated
vendored
@ -2,10 +2,13 @@ package stdcli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/adrg/xdg"
|
||||
)
|
||||
|
||||
func (e *Engine) LocalSetting(name string) string {
|
||||
@ -40,6 +43,15 @@ func (e *Engine) SettingDelete(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) SettingDirectory(name string) (string, error) {
|
||||
dir, err := e.settingFile(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
func (e *Engine) SettingRead(name string) (string, error) {
|
||||
file, err := e.settingFile(name)
|
||||
if err != nil {
|
||||
@ -116,3 +128,20 @@ func (e *Engine) SettingWriteKey(name, key, value string) error {
|
||||
|
||||
return e.SettingWrite(name, string(data))
|
||||
}
|
||||
|
||||
func (e *Engine) localSettingDir() string {
|
||||
return fmt.Sprintf(".%s", e.Name)
|
||||
}
|
||||
|
||||
func (e *Engine) settingFile(name string) (string, error) {
|
||||
if dir := e.Settings; dir != "" {
|
||||
return filepath.Join(dir, name), nil
|
||||
}
|
||||
|
||||
dir, err := xdg.ConfigFile(fmt.Sprintf("%s/%s", e.Name, name))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
7
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
7
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
@ -3,8 +3,9 @@ sudo: false
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.7.3
|
||||
- 1.8.1
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
@ -12,7 +13,7 @@ matrix:
|
||||
- go: tip
|
||||
|
||||
install:
|
||||
- go get github.com/golang/lint/golint
|
||||
- go get golang.org/x/lint/golint
|
||||
- export PATH=$GOPATH/bin:$PATH
|
||||
- go install ./...
|
||||
|
||||
|
||||
4
vendor/github.com/spf13/pflag/README.md
generated
vendored
4
vendor/github.com/spf13/pflag/README.md
generated
vendored
@ -86,8 +86,8 @@ fmt.Println("ip has value ", *ip)
|
||||
fmt.Println("flagvar has value ", flagvar)
|
||||
```
|
||||
|
||||
There are helpers function to get values later if you have the FlagSet but
|
||||
it was difficult to keep up with all of the flag pointers in your code.
|
||||
There are helper functions available to get the value stored in a Flag if you have a FlagSet but find
|
||||
it difficult to keep up with all of the pointers in your code.
|
||||
If you have a pflag.FlagSet with a flag called 'flagname' of type int you
|
||||
can use GetInt() to get the int value. But notice that 'flagname' must exist
|
||||
and it must be an int. GetString("flagname") will fail.
|
||||
|
||||
38
vendor/github.com/spf13/pflag/bool_slice.go
generated
vendored
38
vendor/github.com/spf13/pflag/bool_slice.go
generated
vendored
@ -71,6 +71,44 @@ func (s *boolSliceValue) String() string {
|
||||
return "[" + out + "]"
|
||||
}
|
||||
|
||||
func (s *boolSliceValue) fromString(val string) (bool, error) {
|
||||
return strconv.ParseBool(val)
|
||||
}
|
||||
|
||||
func (s *boolSliceValue) toString(val bool) string {
|
||||
return strconv.FormatBool(val)
|
||||
}
|
||||
|
||||
func (s *boolSliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *boolSliceValue) Replace(val []string) error {
|
||||
out := make([]bool, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *boolSliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func boolSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
|
||||
4
vendor/github.com/spf13/pflag/count.go
generated
vendored
4
vendor/github.com/spf13/pflag/count.go
generated
vendored
@ -46,7 +46,7 @@ func (f *FlagSet) GetCount(name string) (int, error) {
|
||||
|
||||
// CountVar defines a count flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int variable in which to store the value of the flag.
|
||||
// A count flag will add 1 to its value evey time it is found on the command line
|
||||
// A count flag will add 1 to its value every time it is found on the command line
|
||||
func (f *FlagSet) CountVar(p *int, name string, usage string) {
|
||||
f.CountVarP(p, name, "", usage)
|
||||
}
|
||||
@ -69,7 +69,7 @@ func CountVarP(p *int, name, shorthand string, usage string) {
|
||||
|
||||
// Count defines a count flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int variable that stores the value of the flag.
|
||||
// A count flag will add 1 to its value evey time it is found on the command line
|
||||
// A count flag will add 1 to its value every time it is found on the command line
|
||||
func (f *FlagSet) Count(name string, usage string) *int {
|
||||
p := new(int)
|
||||
f.CountVarP(p, name, "", usage)
|
||||
|
||||
38
vendor/github.com/spf13/pflag/duration_slice.go
generated
vendored
38
vendor/github.com/spf13/pflag/duration_slice.go
generated
vendored
@ -51,6 +51,44 @@ func (s *durationSliceValue) String() string {
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) fromString(val string) (time.Duration, error) {
|
||||
return time.ParseDuration(val)
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) toString(val time.Duration) string {
|
||||
return fmt.Sprintf("%s", val)
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) Replace(val []string) error {
|
||||
out := make([]time.Duration, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func durationSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
|
||||
16
vendor/github.com/spf13/pflag/flag.go
generated
vendored
16
vendor/github.com/spf13/pflag/flag.go
generated
vendored
@ -57,9 +57,9 @@ that give one-letter shorthands for flags. You can use these by appending
|
||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||
var flagvar bool
|
||||
func init() {
|
||||
flag.BoolVarP("boolname", "b", true, "help message")
|
||||
flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
|
||||
}
|
||||
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
||||
flag.VarP(&flagval, "varname", "v", "help message")
|
||||
Shorthand letters can be used with single dashes on the command line.
|
||||
Boolean shorthand flags can be combined with other shorthand flags.
|
||||
|
||||
@ -190,6 +190,18 @@ type Value interface {
|
||||
Type() string
|
||||
}
|
||||
|
||||
// SliceValue is a secondary interface to all flags which hold a list
|
||||
// of values. This allows full control over the value of list flags,
|
||||
// and avoids complicated marshalling and unmarshalling to csv.
|
||||
type SliceValue interface {
|
||||
// Append adds the specified value to the end of the flag value list.
|
||||
Append(string) error
|
||||
// Replace will fully overwrite any data currently in the flag value list.
|
||||
Replace([]string) error
|
||||
// GetSlice returns the flag value list as an array of strings.
|
||||
GetSlice() []string
|
||||
}
|
||||
|
||||
// sortFlags returns the flags as a slice in lexicographical sorted order.
|
||||
func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
|
||||
list := make(sort.StringSlice, len(flags))
|
||||
|
||||
174
vendor/github.com/spf13/pflag/float32_slice.go
generated
vendored
Normal file
174
vendor/github.com/spf13/pflag/float32_slice.go
generated
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- float32Slice Value
|
||||
type float32SliceValue struct {
|
||||
value *[]float32
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newFloat32SliceValue(val []float32, p *[]float32) *float32SliceValue {
|
||||
isv := new(float32SliceValue)
|
||||
isv.value = p
|
||||
*isv.value = val
|
||||
return isv
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]float32, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
var temp64 float64
|
||||
temp64, err = strconv.ParseFloat(d, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out[i] = float32(temp64)
|
||||
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) Type() string {
|
||||
return "float32Slice"
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%f", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) fromString(val string) (float32, error) {
|
||||
t64, err := strconv.ParseFloat(val, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return float32(t64), nil
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) toString(val float32) string {
|
||||
return fmt.Sprintf("%f", val)
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) Replace(val []string) error {
|
||||
out := make([]float32, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *float32SliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func float32SliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []float32{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]float32, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
var temp64 float64
|
||||
temp64, err = strconv.ParseFloat(d, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = float32(temp64)
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetFloat32Slice return the []float32 value of a flag with the given name
|
||||
func (f *FlagSet) GetFloat32Slice(name string) ([]float32, error) {
|
||||
val, err := f.getFlagType(name, "float32Slice", float32SliceConv)
|
||||
if err != nil {
|
||||
return []float32{}, err
|
||||
}
|
||||
return val.([]float32), nil
|
||||
}
|
||||
|
||||
// Float32SliceVar defines a float32Slice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []float32 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Float32SliceVar(p *[]float32, name string, value []float32, usage string) {
|
||||
f.VarP(newFloat32SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) {
|
||||
f.VarP(newFloat32SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float32SliceVar defines a float32[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a float32[] variable in which to store the value of the flag.
|
||||
func Float32SliceVar(p *[]float32, name string, value []float32, usage string) {
|
||||
CommandLine.VarP(newFloat32SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) {
|
||||
CommandLine.VarP(newFloat32SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float32Slice defines a []float32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []float32 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Float32Slice(name string, value []float32, usage string) *[]float32 {
|
||||
p := []float32{}
|
||||
f.Float32SliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 {
|
||||
p := []float32{}
|
||||
f.Float32SliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Float32Slice defines a []float32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []float32 variable that stores the value of the flag.
|
||||
func Float32Slice(name string, value []float32, usage string) *[]float32 {
|
||||
return CommandLine.Float32SliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 {
|
||||
return CommandLine.Float32SliceP(name, shorthand, value, usage)
|
||||
}
|
||||
166
vendor/github.com/spf13/pflag/float64_slice.go
generated
vendored
Normal file
166
vendor/github.com/spf13/pflag/float64_slice.go
generated
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- float64Slice Value
|
||||
type float64SliceValue struct {
|
||||
value *[]float64
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newFloat64SliceValue(val []float64, p *[]float64) *float64SliceValue {
|
||||
isv := new(float64SliceValue)
|
||||
isv.value = p
|
||||
*isv.value = val
|
||||
return isv
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]float64, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.ParseFloat(d, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) Type() string {
|
||||
return "float64Slice"
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%f", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) fromString(val string) (float64, error) {
|
||||
return strconv.ParseFloat(val, 64)
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) toString(val float64) string {
|
||||
return fmt.Sprintf("%f", val)
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) Replace(val []string) error {
|
||||
out := make([]float64, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *float64SliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func float64SliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []float64{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]float64, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.ParseFloat(d, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetFloat64Slice return the []float64 value of a flag with the given name
|
||||
func (f *FlagSet) GetFloat64Slice(name string) ([]float64, error) {
|
||||
val, err := f.getFlagType(name, "float64Slice", float64SliceConv)
|
||||
if err != nil {
|
||||
return []float64{}, err
|
||||
}
|
||||
return val.([]float64), nil
|
||||
}
|
||||
|
||||
// Float64SliceVar defines a float64Slice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []float64 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Float64SliceVar(p *[]float64, name string, value []float64, usage string) {
|
||||
f.VarP(newFloat64SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) {
|
||||
f.VarP(newFloat64SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float64SliceVar defines a float64[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a float64[] variable in which to store the value of the flag.
|
||||
func Float64SliceVar(p *[]float64, name string, value []float64, usage string) {
|
||||
CommandLine.VarP(newFloat64SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) {
|
||||
CommandLine.VarP(newFloat64SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float64Slice defines a []float64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []float64 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Float64Slice(name string, value []float64, usage string) *[]float64 {
|
||||
p := []float64{}
|
||||
f.Float64SliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 {
|
||||
p := []float64{}
|
||||
f.Float64SliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Float64Slice defines a []float64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []float64 variable that stores the value of the flag.
|
||||
func Float64Slice(name string, value []float64, usage string) *[]float64 {
|
||||
return CommandLine.Float64SliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 {
|
||||
return CommandLine.Float64SliceP(name, shorthand, value, usage)
|
||||
}
|
||||
3
vendor/github.com/spf13/pflag/go.mod
generated
vendored
Normal file
3
vendor/github.com/spf13/pflag/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/spf13/pflag
|
||||
|
||||
go 1.12
|
||||
0
vendor/github.com/spf13/pflag/go.sum
generated
vendored
Normal file
0
vendor/github.com/spf13/pflag/go.sum
generated
vendored
Normal file
174
vendor/github.com/spf13/pflag/int32_slice.go
generated
vendored
Normal file
174
vendor/github.com/spf13/pflag/int32_slice.go
generated
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- int32Slice Value
|
||||
type int32SliceValue struct {
|
||||
value *[]int32
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newInt32SliceValue(val []int32, p *[]int32) *int32SliceValue {
|
||||
isv := new(int32SliceValue)
|
||||
isv.value = p
|
||||
*isv.value = val
|
||||
return isv
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]int32, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
var temp64 int64
|
||||
temp64, err = strconv.ParseInt(d, 0, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out[i] = int32(temp64)
|
||||
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) Type() string {
|
||||
return "int32Slice"
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%d", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) fromString(val string) (int32, error) {
|
||||
t64, err := strconv.ParseInt(val, 0, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(t64), nil
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) toString(val int32) string {
|
||||
return fmt.Sprintf("%d", val)
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) Replace(val []string) error {
|
||||
out := make([]int32, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *int32SliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func int32SliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []int32{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]int32, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
var temp64 int64
|
||||
temp64, err = strconv.ParseInt(d, 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = int32(temp64)
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetInt32Slice return the []int32 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt32Slice(name string) ([]int32, error) {
|
||||
val, err := f.getFlagType(name, "int32Slice", int32SliceConv)
|
||||
if err != nil {
|
||||
return []int32{}, err
|
||||
}
|
||||
return val.([]int32), nil
|
||||
}
|
||||
|
||||
// Int32SliceVar defines a int32Slice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []int32 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int32SliceVar(p *[]int32, name string, value []int32, usage string) {
|
||||
f.VarP(newInt32SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) {
|
||||
f.VarP(newInt32SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int32SliceVar defines a int32[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a int32[] variable in which to store the value of the flag.
|
||||
func Int32SliceVar(p *[]int32, name string, value []int32, usage string) {
|
||||
CommandLine.VarP(newInt32SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) {
|
||||
CommandLine.VarP(newInt32SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int32Slice defines a []int32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []int32 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int32Slice(name string, value []int32, usage string) *[]int32 {
|
||||
p := []int32{}
|
||||
f.Int32SliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 {
|
||||
p := []int32{}
|
||||
f.Int32SliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Int32Slice defines a []int32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []int32 variable that stores the value of the flag.
|
||||
func Int32Slice(name string, value []int32, usage string) *[]int32 {
|
||||
return CommandLine.Int32SliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 {
|
||||
return CommandLine.Int32SliceP(name, shorthand, value, usage)
|
||||
}
|
||||
166
vendor/github.com/spf13/pflag/int64_slice.go
generated
vendored
Normal file
166
vendor/github.com/spf13/pflag/int64_slice.go
generated
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- int64Slice Value
|
||||
type int64SliceValue struct {
|
||||
value *[]int64
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newInt64SliceValue(val []int64, p *[]int64) *int64SliceValue {
|
||||
isv := new(int64SliceValue)
|
||||
isv.value = p
|
||||
*isv.value = val
|
||||
return isv
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]int64, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.ParseInt(d, 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) Type() string {
|
||||
return "int64Slice"
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%d", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) fromString(val string) (int64, error) {
|
||||
return strconv.ParseInt(val, 0, 64)
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) toString(val int64) string {
|
||||
return fmt.Sprintf("%d", val)
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) Replace(val []string) error {
|
||||
out := make([]int64, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *int64SliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func int64SliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []int64{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]int64, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.ParseInt(d, 0, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetInt64Slice return the []int64 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt64Slice(name string) ([]int64, error) {
|
||||
val, err := f.getFlagType(name, "int64Slice", int64SliceConv)
|
||||
if err != nil {
|
||||
return []int64{}, err
|
||||
}
|
||||
return val.([]int64), nil
|
||||
}
|
||||
|
||||
// Int64SliceVar defines a int64Slice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []int64 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int64SliceVar(p *[]int64, name string, value []int64, usage string) {
|
||||
f.VarP(newInt64SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) {
|
||||
f.VarP(newInt64SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int64SliceVar defines a int64[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a int64[] variable in which to store the value of the flag.
|
||||
func Int64SliceVar(p *[]int64, name string, value []int64, usage string) {
|
||||
CommandLine.VarP(newInt64SliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) {
|
||||
CommandLine.VarP(newInt64SliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int64Slice defines a []int64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []int64 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int64Slice(name string, value []int64, usage string) *[]int64 {
|
||||
p := []int64{}
|
||||
f.Int64SliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 {
|
||||
p := []int64{}
|
||||
f.Int64SliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// Int64Slice defines a []int64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []int64 variable that stores the value of the flag.
|
||||
func Int64Slice(name string, value []int64, usage string) *[]int64 {
|
||||
return CommandLine.Int64SliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 {
|
||||
return CommandLine.Int64SliceP(name, shorthand, value, usage)
|
||||
}
|
||||
30
vendor/github.com/spf13/pflag/int_slice.go
generated
vendored
30
vendor/github.com/spf13/pflag/int_slice.go
generated
vendored
@ -51,6 +51,36 @@ func (s *intSliceValue) String() string {
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *intSliceValue) Append(val string) error {
|
||||
i, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *intSliceValue) Replace(val []string) error {
|
||||
out := make([]int, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = strconv.Atoi(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *intSliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = strconv.Itoa(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func intSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
|
||||
40
vendor/github.com/spf13/pflag/ip_slice.go
generated
vendored
40
vendor/github.com/spf13/pflag/ip_slice.go
generated
vendored
@ -72,9 +72,47 @@ func (s *ipSliceValue) String() string {
|
||||
return "[" + out + "]"
|
||||
}
|
||||
|
||||
func (s *ipSliceValue) fromString(val string) (net.IP, error) {
|
||||
return net.ParseIP(strings.TrimSpace(val)), nil
|
||||
}
|
||||
|
||||
func (s *ipSliceValue) toString(val net.IP) string {
|
||||
return val.String()
|
||||
}
|
||||
|
||||
func (s *ipSliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ipSliceValue) Replace(val []string) error {
|
||||
out := make([]net.IP, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ipSliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ipSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Emtpy string would cause a slice with one (empty) entry
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []net.IP{}, nil
|
||||
}
|
||||
|
||||
26
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
26
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
@ -23,6 +23,32 @@ func (s *stringArrayValue) Set(val string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Append(val string) error {
|
||||
*s.value = append(*s.value, val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Replace(val []string) error {
|
||||
out := make([]string, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i] = d
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = d
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Type() string {
|
||||
return "stringArray"
|
||||
}
|
||||
|
||||
22
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
22
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
@ -62,6 +62,20 @@ func (s *stringSliceValue) String() string {
|
||||
return "[" + str + "]"
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) Append(val string) error {
|
||||
*s.value = append(*s.value, val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) Replace(val []string) error {
|
||||
*s.value = val
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) GetSlice() []string {
|
||||
return *s.value
|
||||
}
|
||||
|
||||
func stringSliceConv(sval string) (interface{}, error) {
|
||||
sval = sval[1 : len(sval)-1]
|
||||
// An empty string would cause a slice with one (empty) string
|
||||
@ -84,7 +98,7 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// --ss="v1,v2" --ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
@ -100,7 +114,7 @@ func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []s
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// --ss="v1,v2" --ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
@ -116,7 +130,7 @@ func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// --ss="v1,v2" --ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
|
||||
@ -136,7 +150,7 @@ func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage str
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// --ss="v1,v2" --ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func StringSlice(name string, value []string, usage string) *[]string {
|
||||
|
||||
149
vendor/github.com/spf13/pflag/string_to_int64.go
generated
vendored
Normal file
149
vendor/github.com/spf13/pflag/string_to_int64.go
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
package pflag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- stringToInt64 Value
|
||||
type stringToInt64Value struct {
|
||||
value *map[string]int64
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newStringToInt64Value(val map[string]int64, p *map[string]int64) *stringToInt64Value {
|
||||
ssv := new(stringToInt64Value)
|
||||
ssv.value = p
|
||||
*ssv.value = val
|
||||
return ssv
|
||||
}
|
||||
|
||||
// Format: a=1,b=2
|
||||
func (s *stringToInt64Value) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make(map[string]int64, len(ss))
|
||||
for _, pair := range ss {
|
||||
kv := strings.SplitN(pair, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
return fmt.Errorf("%s must be formatted as key=value", pair)
|
||||
}
|
||||
var err error
|
||||
out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
for k, v := range out {
|
||||
(*s.value)[k] = v
|
||||
}
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringToInt64Value) Type() string {
|
||||
return "stringToInt64"
|
||||
}
|
||||
|
||||
func (s *stringToInt64Value) String() string {
|
||||
var buf bytes.Buffer
|
||||
i := 0
|
||||
for k, v := range *s.value {
|
||||
if i > 0 {
|
||||
buf.WriteRune(',')
|
||||
}
|
||||
buf.WriteString(k)
|
||||
buf.WriteRune('=')
|
||||
buf.WriteString(strconv.FormatInt(v, 10))
|
||||
i++
|
||||
}
|
||||
return "[" + buf.String() + "]"
|
||||
}
|
||||
|
||||
func stringToInt64Conv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// An empty string would cause an empty map
|
||||
if len(val) == 0 {
|
||||
return map[string]int64{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make(map[string]int64, len(ss))
|
||||
for _, pair := range ss {
|
||||
kv := strings.SplitN(pair, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
return nil, fmt.Errorf("%s must be formatted as key=value", pair)
|
||||
}
|
||||
var err error
|
||||
out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetStringToInt64 return the map[string]int64 value of a flag with the given name
|
||||
func (f *FlagSet) GetStringToInt64(name string) (map[string]int64, error) {
|
||||
val, err := f.getFlagType(name, "stringToInt64", stringToInt64Conv)
|
||||
if err != nil {
|
||||
return map[string]int64{}, err
|
||||
}
|
||||
return val.(map[string]int64), nil
|
||||
}
|
||||
|
||||
// StringToInt64Var defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p point64s to a map[string]int64 variable in which to store the values of the multiple flags.
|
||||
// The value of each argument will not try to be separated by comma
|
||||
func (f *FlagSet) StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) {
|
||||
f.VarP(newStringToInt64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {
|
||||
f.VarP(newStringToInt64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringToInt64Var defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p point64s to a map[string]int64 variable in which to store the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma
|
||||
func StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) {
|
||||
CommandLine.VarP(newStringToInt64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {
|
||||
CommandLine.VarP(newStringToInt64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringToInt64 defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a map[string]int64 variable that stores the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma
|
||||
func (f *FlagSet) StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 {
|
||||
p := map[string]int64{}
|
||||
f.StringToInt64VarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 {
|
||||
p := map[string]int64{}
|
||||
f.StringToInt64VarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringToInt64 defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a map[string]int64 variable that stores the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma
|
||||
func StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 {
|
||||
return CommandLine.StringToInt64P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 {
|
||||
return CommandLine.StringToInt64P(name, shorthand, value, usage)
|
||||
}
|
||||
42
vendor/github.com/spf13/pflag/uint_slice.go
generated
vendored
42
vendor/github.com/spf13/pflag/uint_slice.go
generated
vendored
@ -50,6 +50,48 @@ func (s *uintSliceValue) String() string {
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) fromString(val string) (uint, error) {
|
||||
t, err := strconv.ParseUint(val, 10, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint(t), nil
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) toString(val uint) string {
|
||||
return fmt.Sprintf("%d", val)
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) Append(val string) error {
|
||||
i, err := s.fromString(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.value = append(*s.value, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) Replace(val []string) error {
|
||||
out := make([]uint, len(val))
|
||||
for i, d := range val {
|
||||
var err error
|
||||
out[i], err = s.fromString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*s.value = out
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) GetSlice() []string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = s.toString(d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func uintSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
|
||||
27
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
27
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
@ -11,6 +11,7 @@ import (
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
_ "crypto/sha512" // need for EC keys
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -126,21 +127,23 @@ func jwkEncode(pub crypto.PublicKey) (string, error) {
|
||||
|
||||
// jwsSign signs the digest using the given key.
|
||||
// The hash is unused for ECDSA keys.
|
||||
//
|
||||
// Note: non-stdlib crypto.Signer implementations are expected to return
|
||||
// the signature in the format as specified in RFC7518.
|
||||
// See https://tools.ietf.org/html/rfc7518 for more details.
|
||||
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
|
||||
if key, ok := key.(*ecdsa.PrivateKey); ok {
|
||||
// The key.Sign method of ecdsa returns ASN1-encoded signature.
|
||||
// So, we use the package Sign function instead
|
||||
// to get R and S values directly and format the result accordingly.
|
||||
r, s, err := ecdsa.Sign(rand.Reader, key, digest)
|
||||
switch pub := key.Public().(type) {
|
||||
case *rsa.PublicKey:
|
||||
return key.Sign(rand.Reader, digest, hash)
|
||||
case *ecdsa.PublicKey:
|
||||
sigASN1, err := key.Sign(rand.Reader, digest, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rb, sb := r.Bytes(), s.Bytes()
|
||||
size := key.Params().BitSize / 8
|
||||
|
||||
var rs struct{ R, S *big.Int }
|
||||
if _, err := asn1.Unmarshal(sigASN1, &rs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rb, sb := rs.R.Bytes(), rs.S.Bytes()
|
||||
size := pub.Params().BitSize / 8
|
||||
if size%8 > 0 {
|
||||
size++
|
||||
}
|
||||
@ -149,7 +152,7 @@ func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error)
|
||||
copy(sig[size*2-len(sb):], sb)
|
||||
return sig, nil
|
||||
}
|
||||
return key.Sign(rand.Reader, digest, hash)
|
||||
return nil, ErrUnsupportedKey
|
||||
}
|
||||
|
||||
// jwsHasher indicates suitable JWS algorithm name and a hash function
|
||||
|
||||
4
vendor/golang.org/x/crypto/ssh/terminal/terminal.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/terminal/terminal.go
generated
vendored
@ -947,6 +947,10 @@ func readPasswordLine(reader io.Reader) ([]byte, error) {
|
||||
n, err := reader.Read(buf[:])
|
||||
if n > 0 {
|
||||
switch buf[0] {
|
||||
case '\b':
|
||||
if len(ret) > 0 {
|
||||
ret = ret[:len(ret)-1]
|
||||
}
|
||||
case '\n':
|
||||
return ret, nil
|
||||
case '\r':
|
||||
|
||||
4
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
@ -85,8 +85,8 @@ func ReadPassword(fd int) ([]byte, error) {
|
||||
}
|
||||
old := st
|
||||
|
||||
st &^= (windows.ENABLE_ECHO_INPUT)
|
||||
st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
|
||||
st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
|
||||
st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
|
||||
if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
7
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
7
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
@ -23,10 +23,6 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOV a1+8(FP), A0
|
||||
MOV a2+16(FP), A1
|
||||
MOV a3+24(FP), A2
|
||||
MOV $0, A3
|
||||
MOV $0, A4
|
||||
MOV $0, A5
|
||||
MOV $0, A6
|
||||
MOV trap+0(FP), A7 // syscall entry
|
||||
ECALL
|
||||
MOV A0, r1+32(FP) // r1
|
||||
@ -44,9 +40,6 @@ TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOV a1+8(FP), A0
|
||||
MOV a2+16(FP), A1
|
||||
MOV a3+24(FP), A2
|
||||
MOV ZERO, A3
|
||||
MOV ZERO, A4
|
||||
MOV ZERO, A5
|
||||
MOV trap+0(FP), A7 // syscall entry
|
||||
ECALL
|
||||
MOV A0, r1+32(FP)
|
||||
|
||||
12
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
12
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
@ -9,12 +9,11 @@ package unix
|
||||
import "unsafe"
|
||||
|
||||
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
|
||||
// systems by flock_linux_32bit.go to be SYS_FCNTL64.
|
||||
// systems by fcntl_linux_32bit.go to be SYS_FCNTL64.
|
||||
var fcntl64Syscall uintptr = SYS_FCNTL
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
|
||||
func fcntl(fd int, cmd, arg int) (int, error) {
|
||||
valptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg))
|
||||
var err error
|
||||
if errno != 0 {
|
||||
err = errno
|
||||
@ -22,6 +21,11 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return int(valptr), err
|
||||
}
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return fcntl(int(fd), cmd, arg)
|
||||
}
|
||||
|
||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
||||
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
|
||||
|
||||
29
vendor/golang.org/x/sys/unix/fdset.go
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/fdset.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
// Set adds fd to the set fds.
|
||||
func (fds *FdSet) Set(fd int) {
|
||||
fds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS))
|
||||
}
|
||||
|
||||
// Clear removes fd from the set fds.
|
||||
func (fds *FdSet) Clear(fd int) {
|
||||
fds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS))
|
||||
}
|
||||
|
||||
// IsSet returns whether fd is in the set fds.
|
||||
func (fds *FdSet) IsSet(fd int) bool {
|
||||
return fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0
|
||||
}
|
||||
|
||||
// Zero clears the set fds.
|
||||
func (fds *FdSet) Zero() {
|
||||
for i := range fds.Bits {
|
||||
fds.Bits[i] = 0
|
||||
}
|
||||
}
|
||||
2
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
2
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
|
||||
# Use the Docker-based build system
|
||||
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
||||
$cmd docker build --tag generate:$GOOS $GOOS
|
||||
$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
|
||||
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
8
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
8
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
@ -44,6 +44,7 @@ includes_AIX='
|
||||
#include <sys/stropts.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/termio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
@ -185,6 +186,7 @@ struct ltchars {
|
||||
#include <sys/select.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/can.h>
|
||||
@ -196,6 +198,7 @@ struct ltchars {
|
||||
#include <linux/fanotify.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fscrypt.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/icmpv6.h>
|
||||
@ -495,7 +498,9 @@ ccflags="$@"
|
||||
$2 ~ /^CAN_/ ||
|
||||
$2 ~ /^CAP_/ ||
|
||||
$2 ~ /^ALG_/ ||
|
||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
|
||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||
|
||||
$2 ~ /^FS_IOC_.*ENCRYPTION/ ||
|
||||
$2 ~ /^FSCRYPT_/ ||
|
||||
$2 ~ /^GRND_/ ||
|
||||
$2 ~ /^RND/ ||
|
||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||
@ -522,6 +527,7 @@ ccflags="$@"
|
||||
$2 ~ /^WDIOC_/ ||
|
||||
$2 ~ /^NFN/ ||
|
||||
$2 ~ /^XDP_/ ||
|
||||
$2 ~ /^RWF_/ ||
|
||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
||||
$2 ~ /^CRYPTO_/ ||
|
||||
$2 ~ /^TIPC_/ ||
|
||||
|
||||
19
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
19
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
@ -510,6 +510,23 @@ func SysctlRaw(name string, args ...int) ([]byte, error) {
|
||||
return buf[:n], nil
|
||||
}
|
||||
|
||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := uintptr(SizeofClockinfo)
|
||||
var ci Clockinfo
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != SizeofClockinfo {
|
||||
return nil, EIO
|
||||
}
|
||||
return &ci, nil
|
||||
}
|
||||
|
||||
//sys utimes(path string, timeval *[2]Timeval) (err error)
|
||||
|
||||
func Utimes(path string, tv []Timeval) error {
|
||||
@ -577,8 +594,6 @@ func Futimes(fd int, tv []Timeval) error {
|
||||
return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||
}
|
||||
|
||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
|
||||
19
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
19
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
@ -155,23 +155,6 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (
|
||||
|
||||
//sys getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
|
||||
|
||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := uintptr(SizeofClockinfo)
|
||||
var ci Clockinfo
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != SizeofClockinfo {
|
||||
return nil, EIO
|
||||
}
|
||||
return &ci, nil
|
||||
}
|
||||
|
||||
//sysnb pipe() (r int, w int, err error)
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
@ -333,6 +316,8 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
|
||||
* Wrapped
|
||||
*/
|
||||
|
||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||
|
||||
//sys kill(pid int, signum int, posix int) (err error)
|
||||
|
||||
func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
|
||||
|
||||
2
vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go
generated
vendored
2
vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go
generated
vendored
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin,386,!go1.12
|
||||
// +build darwin,arm,!go1.12
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
6
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
6
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
@ -529,12 +529,6 @@ func PtraceGetRegs(pid int, regsout *Reg) (err error) {
|
||||
return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
|
||||
}
|
||||
|
||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint(countin)}
|
||||
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||
return int(ioDesc.Len), err
|
||||
}
|
||||
|
||||
func PtraceLwpEvents(pid int, enable int) (err error) {
|
||||
return ptrace(PTRACE_LWPEVENTS, pid, 0, enable)
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
generated
vendored
6
vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
generated
vendored
@ -54,3 +54,9 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
||||
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||
return int(ioDesc.Len), err
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
generated
vendored
6
vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
generated
vendored
@ -54,3 +54,9 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||
return int(ioDesc.Len), err
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
generated
vendored
6
vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
generated
vendored
@ -54,3 +54,9 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
||||
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||
return int(ioDesc.Len), err
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
generated
vendored
6
vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
generated
vendored
@ -54,3 +54,9 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||
return int(ioDesc.Len), err
|
||||
}
|
||||
|
||||
153
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
153
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
@ -1575,7 +1575,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
//sys Fchdir(fd int) (err error)
|
||||
//sys Fchmod(fd int, mode uint32) (err error)
|
||||
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
|
||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||
//sys Fdatasync(fd int) (err error)
|
||||
//sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
|
||||
//sys FinitModule(fd int, params string, flags int) (err error)
|
||||
@ -1631,6 +1630,17 @@ func Getpgrp() (pid int) {
|
||||
//sysnb Settimeofday(tv *Timeval) (err error)
|
||||
//sys Setns(fd int, nstype int) (err error)
|
||||
|
||||
// PrctlRetInt performs a prctl operation specified by option and further
|
||||
// optional arguments arg2 through arg5 depending on option. It returns a
|
||||
// non-negative integer that is returned by the prctl syscall.
|
||||
func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
|
||||
ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
|
||||
if err != 0 {
|
||||
return 0, err
|
||||
}
|
||||
return int(ret), nil
|
||||
}
|
||||
|
||||
// issue 1435.
|
||||
// On linux Setuid and Setgid only affects the current thread, not the process.
|
||||
// This does not match what most callers expect so we must return an error
|
||||
@ -1644,6 +1654,30 @@ func Setgid(uid int) (err error) {
|
||||
return EOPNOTSUPP
|
||||
}
|
||||
|
||||
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
|
||||
// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability.
|
||||
// If the call fails due to other reasons, current fsgid will be returned.
|
||||
func SetfsgidRetGid(gid int) (int, error) {
|
||||
return setfsgid(gid)
|
||||
}
|
||||
|
||||
// SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set.
|
||||
// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability
|
||||
// If the call fails due to other reasons, current fsuid will be returned.
|
||||
func SetfsuidRetUid(uid int) (int, error) {
|
||||
return setfsuid(uid)
|
||||
}
|
||||
|
||||
func Setfsgid(gid int) error {
|
||||
_, err := setfsgid(gid)
|
||||
return err
|
||||
}
|
||||
|
||||
func Setfsuid(uid int) error {
|
||||
_, err := setfsuid(uid)
|
||||
return err
|
||||
}
|
||||
|
||||
func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
|
||||
return signalfd(fd, sigmask, _C__NSIG/8, flags)
|
||||
}
|
||||
@ -1666,6 +1700,123 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
|
||||
//sys exitThread(code int) (err error) = SYS_EXIT
|
||||
//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
|
||||
//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
|
||||
//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
|
||||
//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
|
||||
//sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
|
||||
//sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
|
||||
//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
|
||||
//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
|
||||
|
||||
func bytes2iovec(bs [][]byte) []Iovec {
|
||||
iovecs := make([]Iovec, len(bs))
|
||||
for i, b := range bs {
|
||||
iovecs[i].SetLen(len(b))
|
||||
if len(b) > 0 {
|
||||
iovecs[i].Base = &b[0]
|
||||
} else {
|
||||
iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
|
||||
}
|
||||
}
|
||||
return iovecs
|
||||
}
|
||||
|
||||
// offs2lohi splits offs into its lower and upper unsigned long. On 64-bit
|
||||
// systems, hi will always be 0. On 32-bit systems, offs will be split in half.
|
||||
// preadv/pwritev chose this calling convention so they don't need to add a
|
||||
// padding-register for alignment on ARM.
|
||||
func offs2lohi(offs int64) (lo, hi uintptr) {
|
||||
return uintptr(offs), uintptr(uint64(offs) >> SizeofLong)
|
||||
}
|
||||
|
||||
func Readv(fd int, iovs [][]byte) (n int, err error) {
|
||||
iovecs := bytes2iovec(iovs)
|
||||
n, err = readv(fd, iovecs)
|
||||
readvRacedetect(iovecs, n, err)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
||||
iovecs := bytes2iovec(iovs)
|
||||
lo, hi := offs2lohi(offset)
|
||||
n, err = preadv(fd, iovecs, lo, hi)
|
||||
readvRacedetect(iovecs, n, err)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
|
||||
iovecs := bytes2iovec(iovs)
|
||||
lo, hi := offs2lohi(offset)
|
||||
n, err = preadv2(fd, iovecs, lo, hi, flags)
|
||||
readvRacedetect(iovecs, n, err)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func readvRacedetect(iovecs []Iovec, n int, err error) {
|
||||
if !raceenabled {
|
||||
return
|
||||
}
|
||||
for i := 0; n > 0 && i < len(iovecs); i++ {
|
||||
m := int(iovecs[i].Len)
|
||||
if m > n {
|
||||
m = n
|
||||
}
|
||||
n -= m
|
||||
if m > 0 {
|
||||
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
raceAcquire(unsafe.Pointer(&ioSync))
|
||||
}
|
||||
}
|
||||
|
||||
func Writev(fd int, iovs [][]byte) (n int, err error) {
|
||||
iovecs := bytes2iovec(iovs)
|
||||
if raceenabled {
|
||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||
}
|
||||
n, err = writev(fd, iovecs)
|
||||
writevRacedetect(iovecs, n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
||||
iovecs := bytes2iovec(iovs)
|
||||
if raceenabled {
|
||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||
}
|
||||
lo, hi := offs2lohi(offset)
|
||||
n, err = pwritev(fd, iovecs, lo, hi)
|
||||
writevRacedetect(iovecs, n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
|
||||
iovecs := bytes2iovec(iovs)
|
||||
if raceenabled {
|
||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||
}
|
||||
lo, hi := offs2lohi(offset)
|
||||
n, err = pwritev2(fd, iovecs, lo, hi, flags)
|
||||
writevRacedetect(iovecs, n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func writevRacedetect(iovecs []Iovec, n int) {
|
||||
if !raceenabled {
|
||||
return
|
||||
}
|
||||
for i := 0; n > 0 && i < len(iovecs); i++ {
|
||||
m := int(iovecs[i].Len)
|
||||
if m > n {
|
||||
m = n
|
||||
}
|
||||
n -= m
|
||||
if m > 0 {
|
||||
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mmap varies by architecture; see syscall_linux_*.go.
|
||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
@ -70,8 +70,8 @@ func Pipe2(p []int, flags int) (err error) {
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
|
||||
//sys Setfsuid(uid int) (err error) = SYS_SETFSUID32
|
||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
||||
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
@ -55,8 +55,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
@ -98,8 +98,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
|
||||
//sys Setfsuid(uid int) (err error) = SYS_SETFSUID32
|
||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
||||
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
@ -42,8 +42,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
generated
vendored
@ -36,8 +36,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
generated
vendored
@ -31,8 +31,8 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
@ -34,8 +34,8 @@ package unix
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
@ -41,8 +41,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
generated
vendored
@ -34,8 +34,8 @@ import (
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
4
vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
generated
vendored
@ -30,8 +30,8 @@ package unix
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sys setfsgid(gid int) (prev int, err error)
|
||||
//sys setfsuid(uid int) (prev int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
|
||||
28
vendor/golang.org/x/sys/unix/syscall_netbsd.go
generated
vendored
28
vendor/golang.org/x/sys/unix/syscall_netbsd.go
generated
vendored
@ -106,23 +106,6 @@ func direntNamlen(buf []byte) (uint64, bool) {
|
||||
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
|
||||
}
|
||||
|
||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := uintptr(SizeofClockinfo)
|
||||
var ci Clockinfo
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != SizeofClockinfo {
|
||||
return nil, EIO
|
||||
}
|
||||
return &ci, nil
|
||||
}
|
||||
|
||||
//sysnb pipe() (fd1 int, fd2 int, err error)
|
||||
func Pipe(p []int) (err error) {
|
||||
if len(p) != 2 {
|
||||
@ -249,6 +232,14 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
return sendfile(outfd, infd, offset, count)
|
||||
}
|
||||
|
||||
func Fstatvfs(fd int, buf *Statvfs_t) (err error) {
|
||||
return Fstatvfs1(fd, buf, ST_WAIT)
|
||||
}
|
||||
|
||||
func Statvfs(path string, buf *Statvfs_t) (err error) {
|
||||
return Statvfs1(path, buf, ST_WAIT)
|
||||
}
|
||||
|
||||
/*
|
||||
* Exposed directly
|
||||
*/
|
||||
@ -262,6 +253,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
//sys Close(fd int) (err error)
|
||||
//sys Dup(fd int) (nfd int, err error)
|
||||
//sys Dup2(from int, to int) (err error)
|
||||
//sys Dup3(from int, to int, flags int) (err error)
|
||||
//sys Exit(code int)
|
||||
//sys ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||
//sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||
@ -287,6 +279,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
//sys Fpathconf(fd int, name int) (val int, err error)
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error)
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
|
||||
//sys Fstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) = SYS_FSTATVFS1
|
||||
//sys Fsync(fd int) (err error)
|
||||
//sys Ftruncate(fd int, length int64) (err error)
|
||||
//sysnb Getegid() (egid int)
|
||||
@ -343,6 +336,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
//sysnb Settimeofday(tp *Timeval) (err error)
|
||||
//sysnb Setuid(uid int) (err error)
|
||||
//sys Stat(path string, stat *Stat_t) (err error)
|
||||
//sys Statvfs1(path string, buf *Statvfs_t, flags int) (err error) = SYS_STATVFS1
|
||||
//sys Symlink(path string, link string) (err error)
|
||||
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Sync() (err error)
|
||||
|
||||
19
vendor/golang.org/x/sys/unix/syscall_openbsd.go
generated
vendored
19
vendor/golang.org/x/sys/unix/syscall_openbsd.go
generated
vendored
@ -55,23 +55,6 @@ func direntNamlen(buf []byte) (uint64, bool) {
|
||||
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
|
||||
}
|
||||
|
||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := uintptr(SizeofClockinfo)
|
||||
var ci Clockinfo
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != SizeofClockinfo {
|
||||
return nil, EIO
|
||||
}
|
||||
return &ci, nil
|
||||
}
|
||||
|
||||
func SysctlUvmexp(name string) (*Uvmexp, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
@ -248,6 +231,7 @@ func Uname(uname *Utsname) error {
|
||||
//sys Close(fd int) (err error)
|
||||
//sys Dup(fd int) (nfd int, err error)
|
||||
//sys Dup2(from int, to int) (err error)
|
||||
//sys Dup3(from int, to int, flags int) (err error)
|
||||
//sys Exit(code int)
|
||||
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||
//sys Fchdir(fd int) (err error)
|
||||
@ -352,7 +336,6 @@ func Uname(uname *Utsname) error {
|
||||
// clock_settime
|
||||
// closefrom
|
||||
// execve
|
||||
// fcntl
|
||||
// fhopen
|
||||
// fhstat
|
||||
// fhstatfs
|
||||
|
||||
12
vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go
generated
vendored
12
vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go
generated
vendored
@ -459,6 +459,15 @@ const (
|
||||
MAP_SHARED = 0x1
|
||||
MAP_TYPE = 0xf0
|
||||
MAP_VARIABLE = 0x0
|
||||
MCAST_BLOCK_SOURCE = 0x40
|
||||
MCAST_EXCLUDE = 0x2
|
||||
MCAST_INCLUDE = 0x1
|
||||
MCAST_JOIN_GROUP = 0x3e
|
||||
MCAST_JOIN_SOURCE_GROUP = 0x42
|
||||
MCAST_LEAVE_GROUP = 0x3f
|
||||
MCAST_LEAVE_SOURCE_GROUP = 0x43
|
||||
MCAST_SOURCE_FILTER = 0x49
|
||||
MCAST_UNBLOCK_SOURCE = 0x41
|
||||
MCL_CURRENT = 0x100
|
||||
MCL_FUTURE = 0x200
|
||||
MSG_ANY = 0x4
|
||||
@ -483,6 +492,7 @@ const (
|
||||
MS_INVALIDATE = 0x40
|
||||
MS_PER_SEC = 0x3e8
|
||||
MS_SYNC = 0x20
|
||||
NFDBITS = 0x20
|
||||
NL0 = 0x0
|
||||
NL1 = 0x4000
|
||||
NL2 = 0x8000
|
||||
@ -688,7 +698,7 @@ const (
|
||||
SIOCGHIWAT = 0x40047301
|
||||
SIOCGIFADDR = -0x3fd796df
|
||||
SIOCGIFADDRS = 0x2000698c
|
||||
SIOCGIFBAUDRATE = -0x3fd79693
|
||||
SIOCGIFBAUDRATE = -0x3fdf9669
|
||||
SIOCGIFBRDADDR = -0x3fd796dd
|
||||
SIOCGIFCONF = -0x3ff796bb
|
||||
SIOCGIFCONFGLOB = -0x3ff79670
|
||||
|
||||
12
vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go
generated
vendored
12
vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go
generated
vendored
@ -459,6 +459,15 @@ const (
|
||||
MAP_SHARED = 0x1
|
||||
MAP_TYPE = 0xf0
|
||||
MAP_VARIABLE = 0x0
|
||||
MCAST_BLOCK_SOURCE = 0x40
|
||||
MCAST_EXCLUDE = 0x2
|
||||
MCAST_INCLUDE = 0x1
|
||||
MCAST_JOIN_GROUP = 0x3e
|
||||
MCAST_JOIN_SOURCE_GROUP = 0x42
|
||||
MCAST_LEAVE_GROUP = 0x3f
|
||||
MCAST_LEAVE_SOURCE_GROUP = 0x43
|
||||
MCAST_SOURCE_FILTER = 0x49
|
||||
MCAST_UNBLOCK_SOURCE = 0x41
|
||||
MCL_CURRENT = 0x100
|
||||
MCL_FUTURE = 0x200
|
||||
MSG_ANY = 0x4
|
||||
@ -483,6 +492,7 @@ const (
|
||||
MS_INVALIDATE = 0x40
|
||||
MS_PER_SEC = 0x3e8
|
||||
MS_SYNC = 0x20
|
||||
NFDBITS = 0x40
|
||||
NL0 = 0x0
|
||||
NL1 = 0x4000
|
||||
NL2 = 0x8000
|
||||
@ -688,7 +698,7 @@ const (
|
||||
SIOCGHIWAT = 0x40047301
|
||||
SIOCGIFADDR = -0x3fd796df
|
||||
SIOCGIFADDRS = 0x2000698c
|
||||
SIOCGIFBAUDRATE = -0x3fd79693
|
||||
SIOCGIFBAUDRATE = -0x3fdf9669
|
||||
SIOCGIFBRDADDR = -0x3fd796dd
|
||||
SIOCGIFCONF = -0x3fef96bb
|
||||
SIOCGIFCONFGLOB = -0x3fef9670
|
||||
|
||||
5576
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
5576
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5576
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
5576
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5588
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
5588
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5562
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
5562
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
5580
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5698
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
5698
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5698
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
5698
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5550
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
5550
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5696
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
5696
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5676
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
generated
vendored
5676
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
// Code generated by linux/mkall.go generatePtracePair(arm, arm64). DO NOT EDIT.
|
||||
// Code generated by linux/mkall.go generatePtracePair("arm", "arm64"). DO NOT EDIT.
|
||||
|
||||
// +build linux
|
||||
// +build arm arm64
|
||||
17
vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Code generated by linux/mkall.go generatePtraceRegSet("arm64"). DO NOT EDIT.
|
||||
|
||||
package unix
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// PtraceGetRegSetArm64 fetches the registers used by arm64 binaries.
|
||||
func PtraceGetRegSetArm64(pid, addr int, regsout *PtraceRegsArm64) error {
|
||||
iovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))}
|
||||
return ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))
|
||||
}
|
||||
|
||||
// PtraceSetRegSetArm64 sets the registers used by arm64 binaries.
|
||||
func PtraceSetRegSetArm64(pid, addr int, regs *PtraceRegsArm64) error {
|
||||
iovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))}
|
||||
return ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
// Code generated by linux/mkall.go generatePtracePair(mips, mips64). DO NOT EDIT.
|
||||
// Code generated by linux/mkall.go generatePtracePair("mips", "mips64"). DO NOT EDIT.
|
||||
|
||||
// +build linux
|
||||
// +build mips mips64
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user